python爬虫学习笔记(2)-爬取知乎

来源:互联网 发布:c语言吊死鬼游戏 编辑:程序博客网 时间:2024/05/16 17:09

本次的目的是爬取知乎一个问题下面的所有内容。

本次爬取涉及到模拟登陆和异步加载的问题。

一、模拟登陆
1、首先打开登陆界面:https://www.zhihu.com/#signin
2、故意输错密码(请求会少很多,方便我们抓包),暂时不提交,F12打开游览器的开发者选项,勾选Preserve log,点击登陆
这里写图片描述

3、通过单词意思我们可以知道email是提交表单的请求,点开

这里写图片描述
可以看到request url和request method,以及最下面的formdata,是我们故意输错的账号密码,值得关注的是_xsrf,这个似乎是标注游览器从哪一个页面跳转过来,是一个反爬措施。

4、爬取上一个页面(即登录界面)可得到_xsrf值,方法同爬取糗事百科,代码如下:

def get_xrsf():    weburl="https://www.zhihu.com/#signin"    temp_r=requests.get(weburl,headers=loghead)    bsobj=BeautifulSoup(temp_r.text,"html.parser")    return bsobj.find("input",{"name":"_xsrf"}).attrs["value"]

5、回到第三步,模拟登陆涉及到cookie,所以用requests建立会话来处理

s=requests.Session()def log(account,password):    logurl="https://www.zhihu.com/login/email"    formdata={    "email":account,    "password":password,    "_xrsf":get_xrsf()    }    s.headers=loghead    z=s.post(logurl,data=formdata)    print(z.status_code)

formdata构造了我们登录需要的值,用post方法发送给服务器,至于loghead的内容,查看第三步中的request head仿造即可,哪些需要哪些不需要多试试就知道了
放出我的觉得需要的

loghead={"Host":"www.zhihu.com","Referer":"https://www.zhihu.com/","User-Agent":"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36",}

6、至此登录成功,因为是用构建的会话,也不用再考虑cookie的问题,这一段有问题的可以查看requests的官方文档-高级用法

7、因为是常用ip登录,没有遇到验证码的问题,验证码问题的解决方案会在后面放出

二、异步加载
异步加载的概念大家百度一下就好,简单描述一下就是内容不会一下子全部加载出来,而是根据阅读进度加载。
这样就有一个问题,如果像爬取静态页面那样操作,内容会爬取不完整,后面即时加载的内容会丢失。
那么我们滑动鼠标到页面最下面,游览器自动加载剩下内容的时候,游览器又发送了哪些请求来得到新加载内容呢?
抓包!抓下来看看就知道了。
1、这次我们勾选xhr,
这里写图片描述

截图的最后一项引起了我的注意,size有32.1kb,很有可能就是新加载的内容,点开查看一下这里写图片描述

不出所料,我们想要的内容就在里面,返回的数据还是json格式的。

2、点到headers的界面,找到我们需要的url和方法(get),吐槽一下这个url巨长,和其他网站的不大一样,可能也是反扒措施。

3、


上图的Query string parameters里的内容都可以在url里面找到,就不需要再传递一次了,
offset是回答的序号(试出来的)
headers需要加入一个authorization,可以在上图找到
所有需要的数据已经找齐,发起请求即可
再次吐槽巨长的url

def GetAnswersImages(number):    name=1    for offset in range(0,20):        question_url="https://www.zhihu.com/api/v4/questions/" \                      +str(number) +"/answers?include=data%5B*%5D." \        "is_normal%2Cis_collapsed%2Cannotation_action%" \        "2Cannotation_detail%2Ccollapse_reason%" \        "2Cis_sticky%2Ccollapsed_by%2Csuggest_edit%" \        "2Ccomment_count%2Ccan_comment%2Ccontent%" \        "2Ceditable_content%2Cvoteup_count%2Creshipment_settings%" \        "2Ccomment_permission%2Cmark_infos%2Ccreated_time" \        "%2Cupdated_time%2Creview_info%2Crelationship.is_authorized" \        "%2Cis_author%2Cvoting%2Cis_thanked%2Cis_nothelp%2Cupvoted_followees%3Bdata%5B*%" \        "5D.author.follower_count%2Cbadge%5B%3F(type%3Dbest_answerer)%5D.topics&"+"offset="+str(offset)+"&limit=20&sort_by=default"        r=s.get(question_url,headers=downhead)        bs1=BeautifulSoup(r.json()["data"][0]["content"], "html.parser")        for tag in bs1.find_all("img",{"src":re.compile("^http")}):             request.urlretrieve(tag["src"],r"H:\zhihuu\\"+str(name)+".jpg")             print("正在下载第",name,"张图片")             name+=1    print("下载完成,共",name-1,"张图片")

微信spaaarks,完整代码写得有些粗糙就不放了,需要的可以加微信。

我是刚学爬虫不久,欢迎各位指出不足和错误,鞠躬。

原创粉丝点击