有时候我们在利用requests抓取网页时,得到的结果可能与在浏览器中看到的结果不一样:在浏览器中能看到的东西,但是在爬取下来的网页源代码中看不到。这是因为requests获取的都是最原始的HTML文档,而浏览器中的页面则是经过JS处理数据得到的结果,这些数据的来源有很多种,第一种方式是:通过Ajax,第二种方式:在HTML文档中,第三种方式:经过JS和特定的算法实现的。对于第一种情况,原始的界面不会包含某些数据,等原始界面加载完毕后,会在向服务器请求数据,然后将请求的数据经过JS渲染得到界面在显示给用户。
那么重点来了!!!什么是Ajax???------Ajax简介
一张图来看Ajax在浏览器与服务器之间所起的作用:
在知道什么是Ajax之后,那么我们如何利用Ajax来获取数据呢?
首先在浏览器中找到Ajax请求:
以微博为例:
找到我们所要的一些数据,就可以利用requests来模拟Ajax请求了
具体的代码如下
import requests
import json
def getHtml(url):
try:
headers = {
"user-agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.26 Safari/537.36",
"X-Requested-With":"XMLHttpRequest",
"Host":"weibo.com",
"Referer":"https://weibo.com/"
}
params = {
"ajwvr":"6",
"category":"0",
"page":"1",
"lefnav":"0",
"cursor":"",
"__rnd":"1548471816629"
}
response = requests.get(url,headers = headers,params=params)
response.raise_for_status()
response.encoding = response.apparent_encoding
return response.text
except: "爬取失败"
if __name__ == '__main__':
url = "https://weibo.com/a/aj/transform/loadingmoreunlogin?"
page = getHtml(url)
print(page)
说明:
对于params部分参数的说明:
page:控制页码
__rnd:据我推测是个随机数,具体指什么请大神赐教
其他的参数:这些参数不变,小生愚钝,也不知道干嘛
然后再利用json库的loads方法变成字典类型,这样便于后续的操作。
if __name__ == '__main__':
url = "https://weibo.com/a/aj/transform/loadingmoreunlogin?"
page = getHtml(url)
d = json.loads(page)
print(d.get("data"))
html = etree.HTML(d.get("data"))
imgs = html.xpath("//h3[@class = 'list_title_s']/div/text()")
for i in imgs:
print(i.strip())
上面代码中的d就是一个字典,可以取出其中的数据,数据就是下面红色方框内的信息
接下来的那几行代码,我大胆采用lxml库来进行解析,我不知道可不可以用,但我知道利用正则表达式一定可以。
结果我居然成功的提取出来了
我这是第一次利用模拟Ajax来爬取网站,有错误的地方请批评指正!
有兴趣的小伙伴可以一起交流哦!