之前打算爬取一个图片资源网站,但是在翻页时发现它的url并没有改变,无法简单的通过request.get()访问其他页面。据搜索资料,了解到这些网站是通过ajax动态加载技术实现。即可以在不重新加载整个网页的情况下,对网页的某部分进行更新。
这样的设置无疑给初期爬虫新手制造了一些困难。
1、什么是ajax
几个常见的用到ajax的场景。
比如你在逛知乎,你没有刷新过网页,但是你却能看到你关注的用户或者话题有了新动态的消息提示。
还比如,我们在看视频时,可以看到下面的评论没有完全全部加载出来,而是你向下拖动一点,它给你加载一点。
从上述场景你应该也可以发现它的优点:
Ajax技术的核心是XMLHttpRequest对象(简称XHR),可以通过使用XHR对象获取到服务器的数据,然后再通过DOM将数据插入到页面中呈现。虽然名字中包含XML,但Ajax通讯与数据格式无关,所以我们的数据格式可以是XML或JSON等格式。(具体请访问:https://www.w3.org/TR/XMLHttpRequest/)
XMLHttpRequest对象用于在后台与服务器交换数据,具体作用如下:
2、如何爬取ajax动态加载的网页
这里用到的方法是通过分析响应请求,模拟响应参数。再通过requests库的request.post()函数去post相对应的参数即可
具体方法如下:
打开开发者工具,快捷键F12,不行就Fn + F12.
标红的1, network, 在其中可以看到服务器加载过来的资源。
标红的2, 是一个过滤器,你可以按照文件格式筛选。
标红的3,是加载过来的具体文件。
Headers中的request method 中显示我们使用的是POST方法。
而且FROM Data 中有一个参数,page。
利用Form Data 中的数据,编写一个字典,赋值给requests.post()中的data即可
接下来就可以正常访问和翻页了!
更为具体的信息可见:https://zhuanlan.zhihu.com/p/27346009,很感谢其提供的思路和帮助
附源码
import requests
import os
import re
def get_page(url,page_num):
pageList =[]
for i in range(1,page_num +1):
formdata ={'type':'index' ,
'paged': i}
try:
r = requests.post(url,data =formdata)
r.raise_for_status()
r.encoding = r.apparent_encoding
print('链接成功')
p = re.compile(r'href="(http://www.jdlingyu.net/\d{5}/)"')
tempList = re.findall(p,r.text)
for each in tempList:
pageList.append(each)
print('保存页面成功')
tempList = []
except:
print('链接失败')
print(pageList)
return pageList
def get_picure(pageList):
picList = []
for each in pageList:
try:
r = requests.get(each,headers = kv)
r.raise_for_status()
r.encoding = r.apparent_encoding
p = re.compile('http://img.jdlingyu.mobi/[^"]+\.jpg|http://w[wx][23].sinaimg.cn/[^"]+\.jpg')
tempList = re.findall(p,r.text)
for each in tempList:
picList.append(each)
print('保存图片链接成功')
tempList = []
except:
print('保存图片链接失败')
return picList
def down_picture(picList,root):
picList = list(set(picList))
if not os.path.exists(root):
os.mkdir(root)
for each in picList:
path = root + each.split('/')[-1]
if not os.path.exists(path):
r = requests.get(each,headers = kv)
r.raise_for_status()
with open(path,'wb') as f:
f.write(r.content)
print('动图已保存')
else:
print('动图已存在')
url = 'http://www.jdlingyu.net/'
kv = {'User-Agent':'Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.221 Safari/537.36 SE 2.X MetaSr 1.0'}
root = 'D://绝对领域//'
pageList = get_page(url,2)
picList = get_picure(pageList)
down_picture(picList,root)