共计 3031 个字符,预计需要花费 8 分钟才能阅读完成。
GitHub 源码分享
微信搜寻:码农 StayUp
主页地址:https://gozhuyinglong.github.io
源码分享:https://github.com/gozhuyinglong/blog-demos
1. 前言
在网站建设中个别会用到全国行政区域划分,以便于做区域数据分析。
上面咱们用 Python 来爬取行政区域数据,数据起源为比拟权威的国家统计局。爬取的页面为 2020 年统计用区划代码和城乡划分代码。
这里有个疑难,为啥统计局只提供了网页版呢?提供文件版岂不是更不便公众。欢送理解的小伙伴给我留言。
2. 网站剖析
在爬取数据之前要做的便是网站剖析,通过剖析来判断应用何种形式来爬取。
2.1 省份页面
一个动态页面,其二级页面应用的是绝对地址,通过 class=provincetr 的 tr
元素来定位
2.2 城市页面
一个动态页面,其二级页面应用的是绝对地址,通过 class=citytr 的 tr
元素来定位
2.3 区县页面
一个动态页面,其二级页面应用的是绝对地址,通过 class=countytr 的 tr
元素来定位
2.4 城镇页面
一个动态页面,其二级页面应用的是绝对地址,通过 class=towntr 的 tr
元素来定位
2.5 村庄页面
一个动态页面,没有二级页面,通过 class=villagetr 的 tr
元素来定位
3. 装置所需库
通过下面的剖析,应用爬取动态网页的形式即可。上面是一些必要的库,须要提前装置好:Requests、BeautifulSoup、lxml。
3.1 Requests
Requests 是一个 Python 的 HTTP 客户端库,用于拜访 URL 网络资源。
装置 Requests 库:
pip install requests
3.2 BeautifulSoup
Beautifu lSoup 是一个能够从 HTML 或 XML 文件中提取数据的 Python 库。它可能通过指定的转换器实现页面文档的导航、查找、批改等。
装置 BeautifulSoup 库:
pip install beautifulsoup4
3.3 lxml
lxml 是一种应用 Python 编写的库,能够迅速、灵便地解决 XML 和 HTML。
它反对 XML Path Language (XPath) 和 Extensible Stylesheet Language Transformation (XSLT),并且实现了常见的 ElementTree API。
装置 lxml 库:
pip install lxml
4. 代码实现
爬虫分以下几步:
- 应用 Requests 库来获取网页。
- 应用 BeautifulSoup 和 lxml 库解析网页。
- 应用 Python 的 File 来存储数据。
输入文件为:以后 py 文件所在目录,文件名称:area-number-2020.txt
输入后果为:级别、区划代码、名称,两头应用制表符分隔,便于存到 Exce 和数据库中。
上面看具体代码:
# -*-coding:utf-8-*- | |
import requests | |
from bs4 import BeautifulSoup | |
# 依据地址获取页面内容,并返回 BeautifulSoup | |
def get_html(url): | |
# 若页面关上失败,则有限重试,没有后退可言 | |
while True: | |
try: | |
# 超时工夫为 1 秒 | |
response = requests.get(url, timeout=1) | |
response.encoding = "GBK" | |
if response.status_code == 200: | |
return BeautifulSoup(response.text, "lxml") | |
else: | |
continue | |
except Exception: | |
continue | |
# 获取地址前缀(用于绝对地址)def get_prefix(url): | |
return url[0:url.rindex("/") + 1] | |
# 递归抓取下一页面 | |
def spider_next(url, lev): | |
if lev == 2: | |
spider_class = "city" | |
elif lev == 3: | |
spider_class = "county" | |
elif lev == 4: | |
spider_class = "town" | |
else: | |
spider_class = "village" | |
for item in get_html(url).select("tr." + spider_class + "tr"): | |
item_td = item.select("td") | |
item_td_code = item_td[0].select_one("a") | |
item_td_name = item_td[1].select_one("a") | |
if item_td_code is None: | |
item_href = None | |
item_code = item_td[0].text | |
item_name = item_td[1].text | |
if lev == 5: | |
item_name = item_td[2].text | |
else: | |
item_href = item_td_code.get("href") | |
item_code = item_td_code.text | |
item_name = item_td_name.text | |
# 输入:级别、区划代码、名称 | |
content2 = str(lev) + "\t" + item_code + "\t" + item_name | |
print(content2) | |
f.write(content2 + "\n") | |
if item_href is not None: | |
spider_next(get_prefix(url) + item_href, lev + 1) | |
# 入口 | |
if __name__ == '__main__': | |
# 抓取省份页面 | |
province_url = "http://www.stats.gov.cn/tjsj/tjbz/tjyqhdmhcxhfdm/2020/index.html" | |
province_list = get_html(province_url).select('tr.provincetr a') | |
# 数据写入到以后文件夹下 area-number-2020.txt 中 | |
f = open("area-number-2020.txt", "w", encoding="utf-8") | |
try: | |
for province in province_list: | |
href = province.get("href") | |
province_code = href[0: 2] + "0000000000" | |
province_name = province.text | |
# 输入:级别、区划代码、名称 | |
content = "1\t" + province_code + "\t" + province_name | |
print(content) | |
f.write(content + "\n") | |
spider_next(get_prefix(province_url) + href, 2) | |
finally: | |
f.close() |
5. 资源下载
如果你只是须要行政区域数据,那么曾经为你筹备好了,从上面连贯中下载即可。
链接:https://pan.baidu.com/s/18MDd…
提取码:t2eg
6. 爬虫遵循的规定
引自:https://www.cnblogs.com/kongyijilafumi/p/13969361.html
- 恪守 Robots 协定,审慎爬取
- 限度你的爬虫行为,禁止近乎 DDOS 的申请频率,一旦造成服务器瘫痪,约等于网络攻击
- 对于显著反爬,或者失常状况不能到达的页面不能强行冲破,否则是 Hacker 行为
- 如果爬取到他人的隐衷,立刻删除,升高进局子的概率。另外要管制本人的欲望