Python爬虫实战!爬取百度指数并可视化

news2024/11/23 17:19:29

a4fcb6db28da8b8bb89405483babd020.gif

大家好,我是小F~

这两年AI可以说是非常火,尤其是AIGC领域

而这其中很多都是基于Python实现的,比如ChatGPT、AI绘画、声音克隆等等。

cd127a2de73a3d4232f4db38ea2820e9.png

对于普通人来说,想直接学习这些高难度的Python项目,还是比较困难的。

小F是非常建议大家学Python,可以从Python爬虫入门。

相对来说简单一点,可以通过学习爬虫案例来入门Python,为了以后学AI打下基础。

今天就给大家介绍一个百度指数数据爬取的实战案例。

其中为了保证数据采集的稳定与高效,小F使用了亮数据的IP代理

acaddf14c7dcb9a5d641d7de55769546.png

在众多的IP代理提供商中,亮数据(Bright Data) 以其稳定、高效和专业的服务受到了广大用户的青睐,这也是小F选择它的原因。

8e2d73a8af45f3b7f9aa05be27af650c.png

不仅提供代理服务,还有一些数据集。

9226f30c3e0b1c661a54ba4a90ee9ff2.png

首次注册,提供5刀的免费额度,还是不错的。

大家要体验的,可以访问下方二维码,免费领取(联系客服开通免费试用,以备不时之需(比如运行爬虫代码IP被封)。

a7af1f705277a9a97ad9fd9e22f884b2.png

下面就来看一下爬虫实战案例吧~

发现百度指数的加密方式又变了,所以参考知乎一位大佬的代码。

完整代码如下。

import json
import requests
import urllib.request
from datetime import datetime
from datetime import timedelta


# 获取IP代理
def get_proxy():
    opener = urllib.request.build_opener(
        urllib.request.ProxyHandler(
            {'http': 'http://brd-customer-hl_5dede465-zone-try-country-cn:pdqt396jal8m@brd.superproxy.io:22225',
             'https': 'http://brd-customer-hl_5dede465-zone-try-country-cn:pdqt396jal8m@brd.superproxy.io:22225'}))

    response = opener.open('http://lumtest.com/myip.json').read()
    response_str = response.decode('utf-8')
    ip = json.loads(response_str)['ip']

    proxies = {
        "http": "http://{}".format(ip),
        "https": "http://{}".format(ip),
    }

    return proxies


# 解码函数
def decrypt(ptbk, index_data):
    n = len(ptbk)//2
    a = dict(zip(ptbk[:n], ptbk[n:]))
    return "".join([a[s] for s in index_data])


def reCode(data, ptbk):
    data = data['data']
    li = data['userIndexes'][0]['all']['data']
    startDate = data['userIndexes'][0]['all']['startDate']
    year_str = startDate[:4]  # 使用切片取前四个字符,即年份部分
    try:
        # 将年份字符串转换为整数
        year = int(year_str)
        # 根据年份判断是否为闰年
        if (year % 4 == 0 and year % 100 != 0) or (year % 400 == 0):
            year = 366
        else:
            year = 365
    except :
        year =365

    if li =='':
        result = {}
        name = data['userIndexes'][0]['word'][0]['name']
        tep_all = []
        while len(tep_all) < year:
            tep_all.insert(0, 0)
        result["name"] = name
        result["data"] = tep_all
    else:
        ptbk = ptbk
        result = {}
        for userIndexe in data['userIndexes']:
            name = userIndexe['word'][0]['name']
            index_all = userIndexe['all']['data']
            try:
                index_all_data = [int(e) for e in decrypt(ptbk, index_all).split(",")]
                tmp_all = index_all_data
            except:
                tmp_all = []
            while len(tmp_all) < year:
                tmp_all.insert(0, 0)
            result["name"] = name
            result["data"] = tmp_all
    return result


def get_index_data(word, year, proxies):
    words = [[{"name": word, "wordType": 1}]]
    words = str(words).replace(" ", "").replace("'", "\"")
    startDate = f"{year}-01-01"
    endDate = f"{year}-12-31"
    url = f'http://index.baidu.com/api/SearchApi/index?area=0&word={words}&startDate={startDate}&endDate={endDate}'

    # 请求头配置
    headers = {
        "Connection": "keep-alive",
        "Accept": "application/json, text/plain, */*",
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36",
        "Sec-Fetch-Site": "same-origin",
        "Sec-Fetch-Mode": "cors",
        "Sec-Fetch-Dest": "empty",
        "Cipher-Text": "1698156005330_1698238860769_ZPrC2QTaXriysBT+5sgXcnbTX3/lW65av4zgu9uR1usPy82bArEg4m9deebXm7/O5g6QWhRxEd9/r/hqHad2WnVFVVWybHPFg3YZUUCKMTIYFeSUIn23C6HdTT1SI8mxsG5mhO4X9nnD6NGI8hF8L5/G+a5cxq+b21PADOpt/XB5eu/pWxNdwfa12krVNuYI1E8uHQ7TFIYjCzLX9MoJzPU6prjkgJtbi3v0X7WGKDJw9hwnd5Op4muW0vWKMuo7pbxUNfEW8wPRmSQjIgW0z5p7GjNpsg98rc3FtHpuhG5JFU0kZ6tHgU8+j6ekZW7+JljdyHUMwEoBOh131bGl+oIHR8vw8Ijtg8UXr0xZqcZbMEagEBzWiiKkEAfibCui59hltAgW5LG8IOtBDqp8RJkbK+IL5GcFkNaXaZfNMpI=",
        "Referer": "https://index.baidu.com/v2/main/index.html",
        "Accept-Language": "zh-CN,zh;q=0.9",
        'Cookie': '你的cookie'}
    res = requests.get(url, headers=headers, proxies=proxies)
    res_json = res.json()

    if res_json["message"] == "bad request":
        print("抓取关键词:"+word+" 失败,请检查cookie或者关键词是否存在")
    else:
        # 获取特征值
        data = res_json['data']
        uniqid = data["uniqid"]
        url = f'http://index.baidu.com/Interface/ptbk?uniqid={uniqid}'
        res = requests.get(url, headers=headers, proxies=proxies)
        # 获取解码字
        ptbk = res.json()['data']

        return res_json, ptbk


def get_date_list(year):
    """
    获取时间列表
    """
    begin_date = f"{year}-01-01"
    end_date = f"{year}-12-31"
    dates = []
    dt = datetime.strptime(begin_date, "%Y-%m-%d")
    date = begin_date[:]
    while date <= end_date:
        dates.append(date)
        dt += timedelta(days=1)
        date = dt.strftime("%Y-%m-%d")
    return dates


def get_word():
    proxies = get_proxy()
    startyear = 2023
    endyear = 2023
    words = ["Python", "C", "Java", "C#", "JavaScript", "SQL", "Go", "PHP", "MATLAB", "Swift", "Rust"]
    for word in words:
        for year in range(startyear, endyear + 1):
            try:
                data, ptbk  = get_index_data(word, year, proxies)
                res = reCode(data, ptbk)
                dates = get_date_list(year)
                for num, date in zip(res['data'], dates):
                    print(word, num, date)
                    with open('word2.csv', 'a+', encoding='utf-8') as f:
                        f.write(word + ',' + str(num) + ',' + date + '\n')
            except:
                pass


get_word()

只需替换请求头里的cookie值即可,获取方式如下图。

0a8522077813c8c74e06b19c0c31d9eb.png

对于IP代理,可以根据你需要的类型,如无限机房代理、动态住宅代理、机房代理、移动代理,创建代理通道。

进入通道后,可以看到使用指南,以及其它语言的调用案例。

87648225b8e9c1a5719ce3c44051ef85.png

cc372099388bffe204342e33cbae055b.png

具体代码如下。

import json
import urllib.request

opener = urllib.request.build_opener(
    urllib.request.ProxyHandler(
        {'http': 'http://brd-customer-hl_5dede465-zone-try-country-cn:pdqt396jal8m@brd.superproxy.io:22225',
        'https': 'http://brd-customer-hl_5dede465-zone-try-country-cn:pdqt396jal8m@brd.superproxy.io:22225'}))

response = opener.open('http://lumtest.com/myip.json').read()
# 将响应转换为字符串
response_str = response.decode('utf-8')
# 使用json库解析字符串
data = json.loads(response_str)['ip']

# 打印IP地址,每一次打印结果是不一样的,输出例子:73.110.170.116
print(data)

这样就不用担心运行爬虫代码,网站把我自己的ip给封了。

如需体验使用,可以点击左下角【阅读原文】,快速访问,联系客服开通免费试用。

运行代码,成功获取到3000+的数据。

103f7f07bcc577a4caa7c55b9cc8b249.png

接下来使用pynimate进行可视化展示。

具体代码如下。

from matplotlib import pyplot as plt
import pandas as pd
import pynimate as nim

# 中文显示
plt.rcParams['font.sans-serif'] = ['SimHei']  #Windows
plt.rcParams['axes.unicode_minus'] = False


# 更新条形图
def post_update(ax, i, datafier, bar_attr):
    ax.spines["top"].set_visible(False)
    ax.spines["right"].set_visible(False)
    ax.spines["bottom"].set_visible(False)
    ax.spines["left"].set_visible(False)
    ax.set_facecolor("#001219")


# 读取数据
df_data = pd.read_csv('word2.csv', encoding='utf-8', header=None, names=['name', 'number', 'day']).set_index("day")
print(df_data)
# 数据处理,数据透视表
df = pd.pivot_table(df_data, values='number', index=['day'], columns=['name'], fill_value=0).head(30)
print(df)
# 保存
# df = pd.read_csv("word.csv").set_index("day")

# 新建画布
cnv = nim.Canvas(figsize=(12.8, 7.2), facecolor="#001219")
bar = nim.Barplot(
    df, "%Y-%m-%d", "2h", post_update=post_update, rounded_edges=True, grid=False, n_bars=10
)
# 标题设置
bar.set_title("主流编程语言热度排行(百度指数)", color="w", weight=600, x=0.15, size=30)
# 时间设置
bar.set_time(
    callback=lambda i, datafier: datafier.data.index[i].strftime("%Y-%m-%d"), color="w", y=0.2, size=20
)

# 文字颜色设置
bar.set_bar_annots(color="w", size=13)
bar.set_xticks(colors="w", length=0, labelsize=13)
bar.set_yticks(colors="w", labelsize=13)
# 条形图边框设置
bar.set_bar_border_props(
    edge_color="black", pad=0.1, mutation_aspect=1, radius=0.2, mutation_scale=0.6
)
cnv.add_plot(bar)
cnv.animate()
# 显示
# plt.show()
# 保存gif
cnv.save("code", 24, "gif")

结果如下所示。

182b98b208aa8db6dfc5560c1fa76278.gif

万水千山总是情,点个 👍 行不行

推荐阅读

3bf1cb2f52ebbe6a416e2e413b16d18c.jpeg

405de6bd320742f0231e2eec2fbde404.jpeg

c771fdc9798e7e78c64b7f9159b9b9a7.jpeg

···  END  ···

d17f8b5c38b0c55254d243539420cbc1.jpeg

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1489411.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Elixir 依赖 (deps) 调试的小技巧

最近使用 Elixir 有点多, 经常需要观察一些依赖 (Deps) 的实现, 比如想加个日志打印点 IO.inspect 啥的观察下某个变量&#xff0c;才能更好的理解某个 Elixir 的依赖。这里介绍下一些调试的方式: 这里以 yeshan333/ex_integration_coveralls 为例子. 我们先 clone 项目到本地…

Matlab 机器人工具箱 符合动力学

文章目录 1 符合化表示1.1 标准DH动力学1.2 改进DH动力学 质量集中在质心1.2 改进DH动力学 质量集中在末端1.3 程序问题1.3.1 Unable to perform assignment because value of type sym is not convertible to double.1.3.2 CAT arguments dimensions not consistent.参考链接1…

测试用例设计指南

软件测试设计是测试过程中重要的测试活动&#xff0c;怎么样设计测试用例能提高我们测试的效率和质量&#xff0c;从以下几个方面做了简单的讲解。 1、测试用例设计原则 测试用例设计的基本原则包括&#xff1a;有效性、清晰性、可复用性、可维护性、完整性、兼容性、易操作性…

JS利用Worker多线程大文件切片上传

在做前端上传时&#xff0c;会遇到上传大文件&#xff0c;大文件就要进行分片上传&#xff0c;我们整理下思路&#xff0c;实现一个分片上传&#xff0c;最终我们要拿到每一个分片的hash值&#xff0c;index 分片索引&#xff0c;以及分片blob&#xff0c;如下&#xff1a; 一…

递归学习资料

思路 例题 package 递归;public class 反向打印字符串 {public static void main(String[] args) {f("ABC",0);}static void f(String str,int n){if (nstr.length()){return;}f(str,n1);System.out.println(str.charAt(n)"");} }多路递归 递归优化 -剪枝…

(vue)复合型输入框el-input输入数字类型,e,+,-等特殊符号可以输入

(vue)复合型输入框el-input输入数字类型&#xff0c;e&#xff0c;&#xff0c;-等特殊符号可以输入 效果 代码 <el-form-item label"分数区间"><el-inputplaceholder"请输入内容"v-model.number"formInline.scoreIntervalValue"clas…

Oracle 11g升级19c 后部分查询功能很慢

*Oracle 11g升级19c 后部分查询功能很慢 今天生产突然有个查询非常慢&#xff0c;日志显示执行了50秒左右&#xff0c;但是从日志中拿出SQL在PLSQL执行&#xff0c;发现用时不到1秒&#xff0c;查看SQL,怀疑是下面几种原因导致 1、使用函数不当 UNIT.UNIT_CODE LIKE CONCAT(‘…

2核4G云服务器租用价格_2核4G云主机优惠价格_2024年报价

租用2核4G服务器费用价格&#xff0c;2核4G云服务器多少钱一年&#xff1f;1个月费用多少&#xff1f;阿里云2核4G服务器30元3个月、轻量应用服务器2核4G4M带宽165元一年、企业用户2核4G5M带宽199元一年&#xff1b;腾讯云轻量2核4G服务器5M带宽165元一年、252元15个月、540元三…

SEACells从单细胞基因组学数据推断转录和表观基因组细胞状态

摘要 Metacells是从单细胞测序数据中衍生出的细胞分组&#xff0c;代表了高度粒度化、独特的细胞状态。在这里&#xff0c;我们提出了单细胞细胞状态聚合&#xff08;SEACells&#xff09;&#xff0c;这是一种用于识别Metacells的算法&#xff0c;它克服了单细胞数据稀疏性的…

leetcode 2.27

leetcode hot 100 哈希1.字母异位词分组2.最长连续序列 双指针1.盛最多水的容器2.和为 K 的子数组 数组1.除自身以外数组的乘积 哈希 1.字母异位词分组 49. 字母异位词分组 方法一&#xff1a;排序 由于互为字母异位词的两个字符串包含的字母相同&#xff0c;因此对两个字符…

C++设计模式之——桥接模式详解和代码实例

文章目录 桥接模式详解&#xff1a;C代码实例进一步阐述桥接模式的优点和适用场景桥接模式的实际应用场景还包括但不限于以下几种情况&#xff1a; 桥接模式(Bridge Pattern)是一种结构型设计模式&#xff0c;它将抽象部分与其实现部分分离&#xff0c;使它们都可以独立变化。这…

Arduino与processing之间的通信——进阶版

本次需要实现Arduino获取板子的偏转角度并通过串口发送给processing&#xff0c;processing部分根据传输过来的各个轴的偏转角度建立对应偏转角度的3D模型。 这就涉及了两个轴正负方向的偏转&#xff0c;我的实现思路是使用串口传输 字母数字 格式的信息&#xff0c;字母用来判…

Corel 会声会影 2023 激活码 会声会影 2023 序列号生成器

会声会影 2023 已经出来很长时间了&#xff0c;但是对它的热爱一直持续不减&#xff0c;今天我给大家带来2023版本为用户带来的多个全新功能&#xff0c;可以更好的编辑视频&#xff0c;不过软件还是付费的&#xff0c;为此我带来了会声会影 2023序列号生成器&#xff0c;可以轻…

算法沉淀——动态规划之01背包问题(leetcode真题剖析)

算法沉淀——动态规划之01背包问题 01.【模板】01背包02.分割等和子集03.目标和04.最后一块石头的重量 II 01背包问题是一类经典的动态规划问题&#xff0c;通常描述为&#xff1a;有一个固定容量的背包&#xff0c;以及一组物品&#xff0c;每件物品都有重量和价值&#xff0c…

【蓝桥杯】分巧克力

一.题目描述 二.输入描述 三.输出描述 四.问题分析 //分巧克力 #include <iostream> #include <algorithm>using namespace std;const int N1e510; int n,k,h[N],w[N];bool judge(int mid){int cnt0;for(int i0;i<n;i){cnt(h[i]/mid)*(w[i]/mid);if(cnt>k)r…

【短时交通流量预测】基于Elman神经网络

课题名称&#xff1a;基于Elman神经网络的短时交通流量预测 版本时间&#xff1a;2023-04-27 代码获取方式&#xff1a;QQ&#xff1a;491052175 或者 私聊博主获取 模型简介&#xff1a; 城市交通路网中交通路段上某时刻的交通流量与本路段前几个时段的交通流量有关&#…

数仓项目6.0(一)

尚硅谷大数据项目【电商数仓6.0】企业数据仓库项目_bilibili 数据流转过程 用户➡️业务服务器➡️数据库存储➡️数仓统计分析➡️数据可视化 数据仓库处理流程&#xff1a;数据源➡️加工数据➡️统计筛选数据➡️分析数据 数据库不是为了数据仓库服务的&#xff0c;需要…

【牛客】VL63 并串转换

题目 描述 题目描述&#xff1a; 设计一个模块进行并串转换&#xff0c;要求每四位d输为转到一位dout输出&#xff0c;输出valid_in表示此时的输入有效 信号示意图&#xff1a; clk为时钟 rst为低电平复位 valid_in 表示输入有效 d 信号输入 dout 信号输出 波形示意图&…

TypeError: the JSON object must be str, bytes or bytearray, not dict

参考文章&#xff1a;https://blog.csdn.net/yuan2019035055/article/details/124934362 Python基础系列&#xff08;一&#xff09;搞懂json数据解析与字典之间的关系 代码&#xff1a; 报错信息: TypeError: the JSON object must be str, bytes or bytearray, not dict …

光伏并网逆变器低电压穿越控制Simulink模型!

适用平台&#xff1a;MatlabSimulink 简介 当电网突发跌落故障时&#xff0c;电网电压降低会使并网电流增大、母线电压升高。当跌落程度较轻时&#xff0c;并网电流仍在逆变器安全运行的范围内&#xff1b;但跌落程度较深时&#xff0c;会引发逆变器过流和母线过压等问题&…