在 Python 中抓取 Google Books Ngrams Viewer
-
会刮什么
-
先决条件
-
完整代码
-
链接
zwz 100008 zwz 100022 其他 zwz 100023 zwz 100021
会刮什么
与抓取的数据图比较:
先决条件
独立的虚拟环境
简而言之,它创建了一组独立的已安装库,包括可以在同一系统中相互共存的不同 Python 版本,从而防止库或 Python 版本冲突。
如果您之前没有使用过虚拟环境,请查看使用 Virtualenv 和 Poetry](https://serpapi.com/blog/python-virtual-environments-using-virtualenv-and-poetry/)博客文章的专用[Python 虚拟环境教程以熟悉。
📌注意:这不是这篇博文的严格要求。
安装库:
pip install requests, pandas, matplotlib, matplotx
减少被屏蔽的机会
请求可能会被阻止。看看如何减少网页抓取时被阻止的机会,有十一种方法可以绕过大多数网站的阻止。
完整代码
import requests, matplotx
import pandas as pd
import matplotlib.pyplot as plt
params = {
"content": "Albert Einstein,Sherlock Holmes,Bear Grylls,Frankenstein,Elon Musk,Richard Branson",
"year_start": "1800",
"year_end": "2019"
}
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.87 Safari/537.36",
}
html = requests.get("https://books.google.com/ngrams/json", params=params, headers=headers, timeout=30).text
time_series = pd.read_json(html, typ="series")
year_values = list(range(int(params['year_start']), int(params['year_end']) + 1))
for series in time_series:
plt.plot(year_values, series["timeseries"], label=series["ngram"])
plt.title("Google Books Ngram Viewer", pad=10)
matplotx.line_labels() # https://stackoverflow.com/a/70200546/15164646
plt.xticks(list(range(int(params['year_start']), int(params['year_end']) + 1, 20)))
plt.grid(axis="y", alpha=0.3)
plt.ylabel("%", labelpad=5)
plt.xlabel(f"Year: {params['year_start']}-{params['year_end']}", labelpad=5)
plt.show()
导入库:
import requests, matplotx
import pandas as pd
import matplotlib.pyplot as plt
-
requests
提出请求,matplotx
自定义情节线标签。 -
pandas
读取将 JSON 字符串转换为 pandasSeries
将传递给matplotlib
以制作图表。 -
matplotlib
制作时间序列图。
创建搜索查询 URL 参数和请求标头:
# https://docs.python-requests.org/en/master/user/quickstart/#passing-parameters-in-urls
params = {
"content": "Albert Einstein,Sherlock Holmes,Bear Grylls,Frankenstein,Elon Musk,Richard Branson",
"year_start": "1800",
"year_end": "2019"
}
# https://requests.readthedocs.io/en/master/user/quickstart/#custom-headers
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.87 Safari/537.36",
}
-
User-Agent
用于充当“真实”用户访问,因此网站会认为它不是发送请求的机器人或脚本。 -
确保您使用的是最新的
User-Agent
。如果使用旧的User-Agent
,网站可能会将特定请求视为发送请求的机器人或脚本。在whatismybrowser.com检查你的User-Agent
是什么。
通过搜索查询params
,从返回的html
向requests
和read_json()
请求header
:
html = requests.get("https://books.google.com/ngrams/json", params=params, headers=headers, timeout=30).text
time_series = pd.read_json(html, typ="series")
-
"https://books.google.com/ngrams/json"
是一个 Google Book Ngram 查看器 JSON 端点。 URL 中唯一改变的是ngrams/graph
->ngrams/json
。此外,它接受与ngrams/graph
相同的 URL 参数。 -
timeout=30
告诉requsests
在 30 秒后停止等待响应。 -
typ="series"
告诉pandas
从 JSON 字符串中创建一个series
对象。默认为DataFrame
。
添加年份值:
# 1800 - 2019
year_values = list(range(int(params['year_start']), int(params['year_end']) + 1))
-
list()
将创建一个list
值。 -
range()
将遍历来自搜索查询params
的一系列值,在这种情况下,从 1800 到 2019。 -
int()
将字符串查询参数转换为整数。 -
+ 1
也可以获取最后一个值,在这种情况下为 2019 年,否则最后一个值为 2018。
遍历time_series
数据并生成plot
:
for series in time_series:
plt.plot(year_values, series["timeseries"], label=series["ngram"])
label=label
是时间序列图上的线标签。
添加图表标题、标签:
plt.title("Google Books Ngram Viewer", pad=10)
matplotx.line_labels() # https://stackoverflow.com/a/70200546/15164646
plt.xticks(list(range(int(params['year_start']), int(params['year_end']) + 1, 20)))
plt.grid(axis="y", alpha=0.3)
plt.ylabel("%", labelpad=5)
plt.xlabel(f"Year: {params['year_start']}-{params['year_end']}", labelpad=5)
-
pad=10
和labelpad=5
代表标签填充。 -
matplotx.line_labels()
将添加样式标签,这些标签将出现在每行的右侧。 -
plt.xticks()
是 X 轴和range(<code>, 20)
上的刻度,其中 20 是步长。 -
grid()
是网格线和alpha
参数定义了混合(透明度)。 -
ylabel()
/xlabel()
代表y轴和x轴标签。
显示情节:
plt.show()
友情链接
- GitHub 存储库与 Jupyter Notebook
其他
如果您有任何要分享的内容、任何问题、建议或无法正常工作的内容,请随时在评论部分发表评论,或通过 Twitter 与@dimitryzub或[@serp_api]联系(https://twitter.com/serp_api).
您的,Dmitriy 和 SerpApi 团队的其他成员。
加入我们Reddit|Twitter|YouTube
添加功能请求💫 或错误🐞
更多推荐
所有评论(0)