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))</pre>

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("&lt;title&gt;(.*?)&lt;/title&gt;",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']&lt;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文件,任务完成。

最后修改:2019 年 11 月 13 日 12 : 57 AM