• 爬虫获取接口数据


    上一讲讲的是获取静态网页数据的教程,适用于我们要爬取的数据在网页源代码中出现,但是还是有很多的数据是源代码中没有的,需要通过接口访问服务器来获得,下面我就来讲讲如何爬取这类数据。

    以巨潮资讯网爬取比亚迪企业年报为例。

    正常人的操作

    1. 打开巨潮资讯网官网

    2. 找到比亚迪的公告

    3. 在分类里面选择筛选信息,找到自己想要的信息

    爬虫的思路

    获取请求信息

    在正常人的操作第三步,当我们选择一个类别时,毫无疑问浏览器肯定会对服务器发送请求信息,服务器返回信息后我们才能看到想要的信息,看一下怎么获取这个请求:

    1. 按下F12或者是右键检查,进入网络,先清空乱七八糟的网络信息

    2. 当我们选择一个类别时会看到右边多出一个query请求,这个就是我们向服务器发出的请求

    3. 我们可以查看query这条请求的信息

    请求转换为代码

    上一步我们获取到了请求信息,我们就可以使用python造一个请求头,主要包含请求头和请求负载,我们荡当然可以使用比较奔的方法一个一个的复制粘贴,把东西搬到代码上,这里推荐一个工具能自动帮我们把请求格式化我们想要的

    1. 把请求复制下来

    2. Curl命令转代码工具 (sbox.cn)这个在线网站可以直接转换为python代码

    请求返回信息

    请求信息在调试窗口响应上查看,当然也可以通过上一步通过代码获取的返回打印出来查看。

    可以看到,一个个报告主要是在"announcements"数组里,通过直觉"adjunctUrl"可能是报告的存放地址,来验证一下,随便打开一个报告,还是按照老方法查看网络请求,可以看到pdf的请求,是不是就是"adjunctUrl"加上前缀,通过查看多个报告,发现都是这个情况,就可以大胆地去操作了。

    请求url为:‘http://static.cninfo.com.cn/’ + “adjunctUrl”

    保存的文件名称:‘tileSecName’+‘-’+‘announcementTitle’

    完整代码

    import requests
    from urllib import request
    cookies = {
        'JSESSIONID': 'F5C5C5CD40FE076E6139580808BEC6E3',
        'cninfo_user_browse': '002594,gshk0001211,%E6%AF%94%E4%BA%9A%E8%BF%AA',
        '_sp_ses.2141': '*',
        'routeId': '.uc2',
        'insert_cookie': '45380249',
        'SID': 'add3de6c-70ed-4c9b-a201-723fbc753673',
        '_sp_id.2141': 'f35a90ce-a735-4c68-a000-1eb385b581af.1694435068.2.1694520662.1694435105.3aee65c9-094e-48f8-af1d-67b97c9655a9',
    }
    
    headers = {
        'Accept': 'application/json, text/javascript, */*; q=0.01',
        'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6',
        'Connection': 'keep-alive',
        'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
        # 'Cookie': 'JSESSIONID=F5C5C5CD40FE076E6139580808BEC6E3; cninfo_user_browse=002594,gshk0001211,%E6%AF%94%E4%BA%9A%E8%BF%AA; _sp_ses.2141=*; routeId=.uc2; insert_cookie=45380249; SID=add3de6c-70ed-4c9b-a201-723fbc753673; _sp_id.2141=f35a90ce-a735-4c68-a000-1eb385b581af.1694435068.2.1694520662.1694435105.3aee65c9-094e-48f8-af1d-67b97c9655a9',
        'Origin': 'http://www.cninfo.com.cn',
        'Referer': 'http://www.cninfo.com.cn/new/disclosure/stock?plate=&stockCode=002594&orgId=gshk0001211',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36 Edg/116.0.1938.76',
        'X-Requested-With': 'XMLHttpRequest',
    }
    
    data = {
        'stock': '002594,gshk0001211',
        'tabName': 'fulltext',
        'pageSize': '30',
        'pageNum': '1',
        'column': 'szse',
        'category': 'category_ndbg_szsh;',
        'plate': 'sz',
        'seDate': '',
        'searchkey': '',
        'secid': '',
        'sortName': '',
        'sortType': '',
        'isHLtitle': 'true',
    }
    
    response = requests.post(
        'http://www.cninfo.com.cn/new/hisAnnouncement/query',
        cookies=cookies,
        headers=headers,
        data=data,
        verify=False,
    ).json()
    #print(response.find("totalRecordNum"))
    for i in response['announcements']:
        reportName=i['tileSecName']+'-'+i['announcementTitle']
        print(reportName)
        reportUrl = 'http://static.cninfo.com.cn/' + i['adjunctUrl']
        print(reportUrl)
        request.urlretrieve(reportUrl, r'./AnnualReport/'+reportName+'.pdf')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54

    有的分类不只有一页数据

    可以看到"totalpages"这个字段跟页数有关,当只有一页的时候为0,两页的时候为1,请求头只有’pageNum’不一样,请求头’pageNum’与响应‘totalpages’是对应的,我们就可以这样写程序:

    import requests
    from urllib import request
    cookies = {
        'JSESSIONID': '5606FC5CD576740918585289AE035EF6',
        'cninfo_user_browse': '002594,gshk0001211,%E6%AF%94%E4%BA%9A%E8%BF%AA',
        'routeId': '.uc1',
        'SID': 'ebbaf14c-1c51-48b5-8a56-e67112c85c8e',
        '_sp_ses.2141': '*',
        '_sp_id.2141': 'f35a90ce-a735-4c68-a000-1eb385b581af.1694435068.5.1694942471.1694940568.9c03aa1e-99d7-4c7b-95a5-0475f67ce2dc',
    }
    
    headers = {
        'Accept': 'application/json, text/javascript, */*; q=0.01',
        'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6',
        'Connection': 'keep-alive',
        'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
        # 'Cookie': 'JSESSIONID=5606FC5CD576740918585289AE035EF6; cninfo_user_browse=002594,gshk0001211,%E6%AF%94%E4%BA%9A%E8%BF%AA; routeId=.uc1; SID=ebbaf14c-1c51-48b5-8a56-e67112c85c8e; _sp_ses.2141=*; _sp_id.2141=f35a90ce-a735-4c68-a000-1eb385b581af.1694435068.5.1694942471.1694940568.9c03aa1e-99d7-4c7b-95a5-0475f67ce2dc',
        'Origin': 'http://www.cninfo.com.cn',
        'Referer': 'http://www.cninfo.com.cn/new/disclosure/stock?tabName=data&orgId=gshk0001211&stockCode=002594',
        #'User-Agent':'Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36 Edg/116.0.1938.81',
        'X-Requested-With': 'XMLHttpRequest',
    }
    
    data = {
        'stock': '002594,gshk0001211',
        'tabName': 'fulltext',
        'pageSize': '30',
        'pageNum': '1',
        'column': 'szse',
        'category': 'category_sf_szsh;',
        'plate': 'sz',
        'seDate': '',
        'searchkey': '',
        'secid': '',
        'sortName': '',
        'sortType': '',
        'isHLtitle': 'true',
    }
    
    proxies = {
        'http': 'http://60.182.197.86:8888',
        'https': 'https://60.182.197.86:8888'
    }
    
    response = requests.post(
        'http://www.cninfo.com.cn/new/hisAnnouncement/query',
        cookies=cookies,
        headers=headers,
        data=data,
        #proxies=proxies,    #使用代理ip,防止反爬
        verify=False,
    ).json()
    
    print('总的页数:'+str(response['totalpages']))
    print('总的数目:'+str(response['totalRecordNum']))
    num=0
    for i in range(1,2+response['totalpages']):
        #print(i)
        data['pageNum']=i
        response = requests.post(
            'http://www.cninfo.com.cn/new/hisAnnouncement/query',
            cookies=cookies,
            headers=headers,
            data=data,
            #proxies=proxies,  # 使用代理ip,防止反爬
            verify=False,
        )
        if response.status_code==200:
            print(response.text)
            response=response.json()
            for j in response['announcements']:
                reportName=j['tileSecName']+'-'+j['shortTitle']
                #print(reportName)
                reportUrl = 'http://static.cninfo.com.cn/' + j['adjunctUrl']
                #print(reportUrl)
                request.urlretrieve(reportUrl, r'./AnnualReport/'+reportName.replace("/","-")+'.pdf')
                print(num)
                num=num+1
                print(r'./AnnualReport/'+reportName+'.pdf'+'下载完成')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
  • 相关阅读:
    前端基础一:用Formdata对象来上传图片的原因
    TYWZOJ 礼品配对包装 题解
    商业化广告--体系学习-- 10 -- 业务实战篇 -- 效果优化:如何一步步从提升曝光量深入到提升销量?
    ESD门禁闸机的使用说明
    TS和JS的区别
    MongoDB 分片集群
    删除两个字典中非公共的键和值
    Codeforces Round #824 (Div. 2)
    mybatis动态sql语法
    如何将原始按照word为单位索引标识的数据集修改为以char单位
  • 原文地址:https://blog.csdn.net/small_planet/article/details/132993880