python爬虫入门篇(二)

往期文章

python爬虫入门篇(一)


目录

往期文章

前言

一、为什么不能直接打开开发者工具

① 误判开发者工具中的Elements(元素)就是源代码

② 为什么源代码和Elements显示的不一样呢?

③ 那怎么把实时数据放在网页上呢?

④ api(接口)是什么东西?

二、如何找到api(接口)

三、成果展示

四、完整代码


前言

还没看过前一篇的尽可能去看前一篇文章 有基础的记住不要一来就打开开发者工具就好


一、为什么不能直接打开开发者工具

① 误判开发者工具中的Elements(元素)就是源代码

        因为我们发出请求的第一个请求到的文件就是网页的源代码文件(查看源代码快敏键 ctrl + U)

② 为什么源代码和Elements显示的不一样呢?

        因为大部分网页是动态的,比如 股票市场 数据是实时更新的 那么我们不可预知,也可能写很多个网页去一个一个替换,用户还要刷新才能得到数据,这是不可能的。

③ 那怎么把实时数据放在网页上呢?

        通过JavaScript把接口(api)数据放到html显示的内容中去

④ api(接口)是什么东西?

        接口可以类比于银行前台小姐,如果你要取钱,你可以跟小姐说明并且出示你的身份证明,她去给你取出来交给你。这就是接口做的事,你把你的cookie或者请求头给它,它判断你是否能请求到这些数据,然后再把数据交给你。

-

那么说到这了,这不就好办了嘛,我们只要找到接口,然后发起请求,收到数据,再进行整理,可视化做出你想要的东西。

-

二、如何找到api(接口)


emmm 这个找个网站给大家当例子,不是恶意爬取

我就找一个网上应该没有人爬过的国家统计局官网 (放心安全的很 你们也可以自己去搜索国家统计局一样的,点击高级,然后继续访问就可以进入了)

-

进去的时候可以看到这些数据

 ok 老方法ctrl+u 看看源代码 可以看出来数据是不在源代码中的 源代码中有很多的JavaScript语句,我们就可以判断这个网站是一个动态的网站

 现在我们再打开我们的开发者工具(f12或者fn+f12) 然后在search框中输入居民消费价格指数这句话

你就会发现哦哦哦哦哦 有个文件里面有这么个数据 ok恭喜你找到了api接口

 然后点击进入找到网址 这里解释一下network(开发者工具)里面的一些字段含义:

最后先大胆尝试 有不懂的可以私信问我(24h内回)

三、成果展示

把数据放入exel表内 

-

然后制作好几副简单的柱状图

 ok 这是很久之前的成果了 不是很注重可视化这种东西 不要介意

-

四、完整代码

这个代码做了个异步 其实还好不是很需要 可以看看这串代码然后照着思路打还是比较简单的

import json
import pandas as pd
import matplotlib.pyplot as plt
import asyncio
import aiohttp
import aiofiles
datatool = []
new_data = []
index = []
dname = []
# from functools import wraps #下面和这个都是为了重写close
# from asyncio.proactor_events import _ProactorBasePipeTransport
# def silence_event_loop_closed(func):#重写close
#     @wraps(func)
#     def wrapper(self, *args, **kwargs):
#         try:
#             return func(self, *args, **kwargs)
#         except RuntimeError as e:
#             if str(e) != 'Event loop is closed':
#                 raise
#     return wrapper
#
# _ProactorBasePipeTransport.__del__ = silence_event_loop_closed(_ProactorBasePipeTransport.__del__)###重写close

async def get_url():#获取url
    url = "https://data.stats.gov.cn/easyquery.htm?m=QueryData&dbcode=hgyd&rowcode=zb&colcode=sj&wds=%5B%5D&dfwds=%5B%7B%22wdcode%22%3A%22sj%22%2C%22valuecode%22%3A%22LAST36%22%7D%5D&k1=1657617147842"
    urln = "https://data.stats.gov.cn/easyquery.htm?m=QueryData&dbcode=hgyd&rowcode=zb&colcode=sj&wds=%5B%5D&dfwds=%5B%7B%22wdcode%22%3A%22sj%22%2C%22valuecode%22%3A%22LAST36%22%7D%5D&k1=1657597568517"
    await get_double(url,urln)#因为太多io操作如果不用多线程要几分钟
async def get_double(url,urln):#获取源代码
    tasks = []
    headers = {
        "User-Agent": "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.114 Mobile Safari/537.36 Edg/103.0.1264.49",
        "X-Requested-With": "XMLHttpRequest",
        "Cookie": "JSESSIONID=SwzsdHSGW6TNLf8RIfCn956tULPRHzkoUL74rrs6_qB4E1Zii07W!1558993049; u=1",
        "Host": "data.stats.gov.cn",
        "Referer": "https://data.stats.gov.cn/easyquery.htm?cn=A01",
        "verify":"False"
    }
    async with aiohttp.ClientSession(connector=aiohttp.TCPConnector(limit=64,verify_ssl=False)) as session:#因为访问要ssl安全验证,把它去掉,也可以直接在TCPConnector里边修改把verify = Ture
        async with session.request('get',url,params=headers) as re:
            resp = await re.text(encoding="utf-8")#获取encoding = 'utf'的源代码
    async with aiohttp.ClientSession(connector=aiohttp.TCPConnector(limit=64,verify_ssl=False)) as session2:
        async with session2.request('get',urln,params=headers) as re2:
            respn = await re2.text(encoding="utf-8")
    respn_json = json.loads(respn)#转换为字典,python语言
    resp_json = json.loads(resp)
    tasks.append(asyncio.create_task(find_data(resp_json,respn_json)))#调用find_data
    await asyncio.wait(tasks)#创建任务
async def find_data(resp,respn):
    tasks = []
    for i in range(1,len(resp['returndata']['datanodes'])):
        data = resp['returndata']['datanodes'][i]['data']['strdata']#找到基本数据
        datatool.append(data)#添加到空列表内
    print(len(datatool))
    new_data.append(datatool[0:35])
    new_data.append(datatool[36:71])
    new_data.append(datatool[72:107])
    new_data.append(datatool[108:143])
    new_data.append(datatool[144:179])
    new_data.append(datatool[180:215])
    new_data.append(datatool[216:251])
    new_data.append(datatool[252:287])
    new_data.append(datatool[288:323])#无脑整理一些数据
    for n in range(35):
        time = respn['returndata']['wdnodes'][1]['nodes'][n]['cname']#获取时间数据
        index.append(time)
    for item in range(9):
        dname.append(resp['returndata']['wdnodes'][0]['nodes'][item]['cname'])#获取标题
    tasks.append(asyncio.create_task(save_data(index,dname,new_data)))
    await asyncio.wait(tasks)#调用save_data
async def save_data(index,dname,new_data):
    df = pd.DataFrame(columns=index,index=dname,data=new_data)#做一个表,标题,横纵坐标数据
    pd.set_option('display.max_rows',None)
    pd.set_option('display.max_columns',None)#把省略部分显示出来
    pd.set_option("display.unicode.ambiguous_as_wide",True)
    pd.set_option("display.unicode.east_asian_width",True)#对齐
    pd.set_option('display.width',1000)
    print(df)
    df.to_excel("消费数据.xls")
    async with aiofiles.open('消费数据','w',encoding='utf-8') as f:
        await f.write(str(df))#保存一下数据
    plt.rcParams['font.sans-serif'] = ['SimHei']
    plt.rcParams['axes.unicode_minus'] = False##中文显示问题
    for page in range(9):#用循环做多个表
        a = page
        b = a+35
        plt.title(dname[page])
        plt.bar(index, datatool[a:b])
        plt.tick_params(labelsize=7)
        plt.xticks(rotation=60)
        plt.show()
        a = b+1
    print('over!')#显示程序成功完成
asyncio.run(get_url())#跑起来



  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

暴风雨544

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值