requests真的是一个非常强大的http库,简单几行就可以实现非常强大的功能。
下面使用了requests的定义header、cookies、data、session。
伪装了目标网站前台js的访问情况,根据增减header并执行,返回的不同提示语句,判断目标判定非法访问的依据是referer。
在header中可以直接定义referer,这样就可以去json接口中快速的得到想要的数据了。
下面是简陋的基于python3的示例代码。
import requests
cookies={
'user_key':',
'SERVERID':'
}
#创建session
s = requests.Session()
r=s.get('https://m.wandougongzhu.cn')
cookies['user_key']=r.cookies['user_key']
cookies['SERVERID']=r.cookies['SERVERID']
def get_json(url,payload,cookies):
headers={
'Accept':'application/json',
'Accept-Encoding':'gzip, deflate',
'Accept-Language':'zh-CN,zh;q=0.8,en;q=0.6',
'Connection':'keep-alive',
'Content-Type':'application/x-www-form-urlencoded',
'DNT':'1',
'Host':'m.wandougongzhu.cn',
'Origin':'https://m.wandougongzhu.cn',
'Referer':'https://m.wandougongzhu.cn',
'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.87 Safari/537.36',
'X-Requested-With':'XMLHttpRequest'
}
r=s.post(url,data=payload,headers=headers,cookies=cookies)
return r.json()
'
https://m.wandougongzhu.cn/search/ajaxGoods
payload={
'page':1,
'count':20,
'cat':167
}
'
payload={
'page':1,
'count':20,
'cat':167
}
print(get_json('https://m.wandougongzhu.cn/search/ajaxGoods',payload,cookies))
2016-08-12
今天正式准备抓数据,发现目标名没有验证session和cookies,于是把那些不验证的都删掉了。
我们要保证取数据的高效,一切妨碍速度的与取数据无关的,都可以不管,因为我们的目标就是数据呀。
有时间写一下kaola的数据怎么拿的吧,那个还挺麻烦的,费了好多事。
使用的代码
import requests
import os
import re
import codecs
import time
#from bs4 import BeautifulSoup
global headers
headers={
'Accept':'application/json',
'Accept-Encoding':'gzip, deflate',
'Accept-Language':'zh-CN,zh;q=0.8,en;q=0.6',
'Content-Type':'application/x-www-form-urlencoded',
'DNT':'1',
'Host':'m.wandougongzhu.cn',
'Origin':'https://m.wandougongzhu.cn',
'Referer':'https://m.wandougongzhu.cn',
'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.87 Safari/537.36',
'X-Requested-With':'XMLHttpRequest'
}
#获取接口数据
def get_Json(url,payload):
try:
r=requests.post(url,data=payload,headers=headers)
return r.json()
except:
return False
#获取评论数,方法1
def get_Comment(goods_id):
payload={
'goods_id':goods_id,
'user_id':',
'start':0,
'count':20,
'user_comment_id':0
}
data=False
while data==False:
data=get_Json('https://m.wandougongzhu.cn/comment/ajaxGoodsCommentList',payload)
time.sleep(2)
return str(data['data']['data'].__len__())
#获取评论数,方法2
def get_Comment_2(goods_id):
html=requests.get('https://m.wandougongzhu.cn/comment/goodscomment?goods_id={0}'.format(goods_id),headers=headers)
#若网页请求失败,那么返回0
if html.status_code!=200:
return '0'
#soup=BeautifulSoup(html.text,'lxml')
#这里title是一个对象不是一个字符串,所以直接使用正则会报错,需要在后面加上title才可以正确执行
#如果网页不为空那么寻找title中的评论数
Comment=re.findall("<title>(.*?)</title>",html.text)
Comment=re.findall("\d+",Comment[0])
#如果查找数字正则返回空,那么说明评论数小于10条,使用第一种方法获取评论数
if Comment==[]:
# return get_Comment(goods_id)
return '少于20'
else:
return Comment[0]
#存储所有数据
def save_csv(data,filename):
str='
for i in data:
str+='"'+'","'.join(i)+"\"\n"
f=codecs.open(filename,'w','utf-8')
f.write(str)
f.close()
# payload={
# 'page':1,
# 'count':20,
# 'cat':2
# }
# r_json=get_Json('https://m.wandougongzhu.cn/search/ajaxGoods',payload)
# print(r_json)
# os._exit(0)
#code
pre_sale=['非预售','预售']
#记录数据
result_list=[]
#获取所有分类
ajaxGetAll=get_Json('https://m.wandougongzhu.cn/category/ajaxGetAll',None)
#当前抓取分类
category="家居生活"
for i in ajaxGetAll['data']['list']:
cat_id =i['cat_id']
cat_name =i['cat_name']
if cat_name!=category:
continue
for o in i['sub']:
cat_id_2 =o['cat_id']
cat_name_2 =o['cat_name']
print(cat_id,cat_name,cat_id_2,cat_name_2)
page = 1
while True:
payload={
'page':page,
'count':20,
'cat':cat_id_2
}
r_json=False
while r_json==False:
r_json=get_Json('https://m.wandougongzhu.cn/search/ajaxGoods',payload)
if r_json==False:
time.sleep(5)
#翻页+1
page+=1
#处理数据
for p in r_json['data']['list']:
result_list.append(
(
#品牌
p['brand_name'],
#价格
str(p['final_price']),
#名称
p['goods_name'],
#slogan
#p['slogan'],
#display_flag
','.join(p['display_flag']),
#商品id
str(p['goods_id']),
#预售
pre_sale[int(p['is_pre_sale'])],
#img_bottom_desc:库存紧张
#p['img_bottom_desc'],
#直供,独家
#p['right_corner_img'],
#residue_count:库存
#p['residue_count'],
#评论数
get_Comment_2(p['goods_id']),
cat_name,
cat_name_2,
"https://m.wandougongzhu.cn/product/{0}.html".format(p['goods_id'])
)
)
#如果总数比当前取到的数量要多,那么跳出
if r_json['data']['total']<page*20:
print('{0}done.'.format(r_json['data']['total']))
break
print(result_list.__len__())
save_csv(result_list,'wandou_{0}.csv'.format(category))
在最外层我是这样写的
#当前抓取分类
category="家居生活"
for i in ajaxGetAll['data']['list']:
cat_id =i['cat_id']
cat_name =i['cat_name']
if cat_name!=category:
continue
这里是为了防止出现各种异常错误,导致前面抓到的数据全泡汤的一种措施,通过改变category的值,来逐个抓取数据,这样即使崩溃了也只是当前顶级分类数据抓不到,不会影响之前抓到的数据。
在实际抓取过程中,发现目标会出现500错误,猜测是目标网络阻塞或者对多次访问有限制,使用time.sleep(3)来等待3秒重新抓取就可以了。
整理一下csv文件,任务完成。