您的位置:首页 > Web前端 > JavaScript

爬虫之爬取知乎下某个问题下的全部图片(处理AJAX请求,解析json数据)

2017-05-25 20:47 786 查看
(直接需要代码的看最后面,前面只是分析)  

当你查看知乎某个问题的答案时,通过普通的方法爬取页面,你发现只能爬取一页的内容,当你点击下一页时,浏览器地址并没有发生变化,这种技术叫做AJAX,每次载入的只是部分数据,当知道这个后,就可以构造特殊的头部来请求获得数据。

知乎问题下的解析:

可以看到请求页面的方式GET,请求的地址为Request URL,请求头的构成为Request Header的内容,有点长是不是。



Request Header:



还有一个就是Query String Parameters



 

这是什么呢,这就是我们Request URL的请求的数据部分了,他是怎么区分页面的呢,我们看第二页的请求数据



两者不同的是 offset这个值,而知乎一个页面的回答数量刚好是20,也就是差值。

到这里我们就可以知道怎么样获取我们请求的数据了:

用GET方法向指定URL发送我们的请求数据

下面是代码实现:

import urllib.request
import json
import urllib.parse
import re
import random
n=0
for i in range(0,10):                                                                           #爬取十页的回答的图片
url='https://www.zhihu.com/api/v4/questions/27761934/answers?'                      #请求URL地址
data={}
head={}
#head为请求头部封装
head['User-Agent']='Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36'
head['accept']='application/json, text/plain, */*'
# head['Accept-Encoding']='utf-8, deflate, sdch, br'
head['Accept-Language']='zh-CN,zh;q=0.8'
head['Referer']='https://www.zhihu.com/question/27761934'
head['authorization']='oauth c3cef7c66a1843f8b3a9e6a1e3160e20'
head['Connection']='keep-alive'
head['host']='www.zhihu.com'
head['Cookie']='q_c1=cb235bc32c3c4ff6a13d539ab32932ed|1491640993000|1491640993000;' \
' r_cap_id="OTk4MDc1ZTYzZTYxNDhkMGFkZmMzZmMyY2MzYTQ0MWM=|1492689948|ea65e09abdd21db7eecd997d1e7689d7213005c8"; ' \
'cap_id="ZWY2NDA1MTc3ZjAzNDc2MWFmNTQ4YjFkY2NhNzdmZjM=|1492689948|16df8cfc942dcae5adc9ffa5395afbdcc87bf39a";' \
' l_cap_id="ZGNkOGVmZTgzNDk0NGJjOTljMzU0Mjc0MGY2YmU1ODE=|1492689948|2768d12cd0236bb96722f7216b307ba799d4bf19"; ' \
'aliyungf_tc=AQAAABxPakPO4goAgVG3PSefHqc6PP2k; acw_tc=AQAAAEUxcRqsHQwAgVG3PZaK3p0hk5Lq'
#data为数据部分
data['sort_by']='default'
data['include']='data[*].is_normal,is_sticky,collapsed_by,suggest_edit,comment_count,' \
'can_comment,content,editable_content,voteup_count,reshipment_settings,' \
'comment_permission,mark_infos,created_time,updated_time,' \
'relationship.is_authorized,is_author,voting,is_thanked,is_nothelp,' \
'upvoted_followees;data[*].author.badge[?(type=best_answerer)].topics'
data['limit']=20
data['offset']=3+20*i

data=urllib.parse.urlencode(data).encode('utf-8')
req=urllib.request.Request(url,data,head,method='GET')
#需指定方法,默认是为POST的
req = urllib.request.urlopen(req)
re_data = req.read().decode('gbk')
print(re_data)
pe='https:.{0,80}jpg'                                                   #构造的正则,有点丑陋。。。
url1=re.compile(pe)
num=0

q=random.randint(1,20)
for x in url1.findall(re_data):
if 'https'  in x:
print(x)
try:
if(num%4==0):
urllib.request.urlretrieve(x, 'F:\\ccc3\\test\\mmmmmm'+str(q)+'%s.jpg' % num)
print('下载第'+str(n) + '张图片')
n+=1
except:print('error')
num +=1








其中head的cookie,host,connection等都是可以省略的。

已知缺陷:json里同一个链接出现四次,我用num处理的有点难看

有最大爬取数,不超过一千,可以用ip池解决

正则丑陋。

爬取别的问题需要修改的是URL里的数字及head['Referer']里的数字,数字为问题的代码,代码为:

里面的数字,如果代码不能运行请修改cookie和authorization为自己的.

如还不能运行,评论或者私信我










                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  python ajax json 图片 爬虫