python脚本抓取省市县区乡镇村庄(五级行政区划)
用python脚本抓取省市县区乡镇村庄(五级行政区划)的过程如下:
1,抓取国家统计局官网上的行政区划名称和对应的代码(5级是不同的网页,所以涉及多层跳转);
2,数据量大约几十万条,频繁访问考虑防屏蔽问题;
3,各层级网页结构有微调需要做兼容处理;
4,大量http/https请求需做好异常处理以提高成功抓取全部结果的概率;
完整python代码:
import requests
from bs4 import BeautifulSoup
import random
import time urlPrefix = 'http://www.stats.gov.cn/tjsj/tjbz/tjyqhdmhcxhfdm/2021/' def myRequest(url):
user_agent_list = ["Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36 QIHU 360SE",
"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36",
"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36",
"Mozilla/5.0 (Windows NT 10.0; WOW64) Gecko/20100101 Firefox/61.0",
"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36",
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.62 Safari/537.36",
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36",
"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)",
"Mozilla/5.0 (Macintosh; U; PPC Mac OS X 10.5; en-US; rv:1.9.2.15) Gecko/20110303 Firefox/3.6.15"]
headers = {'User-Agent': random.choice(user_agent_list)}
requests.adapters.DEFAULT_RETRIES = 5 # 增加重连次数
s = requests.session()
s.keep_alive = False # 关闭多余连接
try:
return s.get(url, headers=headers) # Getting page HTML through request
except (requests.exceptions.ReadTimeout, requests.exceptions.Timeout, requests.exceptions.ConnectTimeout) as e:
print(e)
time.sleep(random.randint(1, 5))
return s.get(url, headers=headers) # Getting page HTML through request
except requests.exceptions.ConnectionError as e:
print(e)
time.sleep(random.randint(1, 5))
return s.get(url, headers=headers) # Getting page HTML through request
except Exception as e:
raise e def Writefile(content, tag):
# 将数据输出文件中,注意点1. 所指定的盘存在,2. 使用file=
fp = open("D:/pythonWorkspace/webSpiders-Region-"+tag+".txt", "a+", encoding='utf-8') # a+ 如果文件不存在就创建。存在就在文件内容的后面继续追加
print(content, file=fp)
fp.close() def villageFun(TownID, villagePage):
print('villageFun> '+TownID+','+villagePage)
page = myRequest(urlPrefix+villagePage) # Getting page HTML through request
if(200 == page.status_code):
soup = BeautifulSoup(page.content, 'html.parser') # Parsing content using beautifulsoup links = soup.select("table tbody tr.villagetr") # Selecting all of the anchors with titles
first10 = links # Keep only the first 10 anchors
for anchor in first10:
myItem = anchor.select("td")
if ([] != myItem):
print('5'+','+myItem[0].text+','+myItem[2].text+','+TownID) # Display the innerText of each anchor
Writefile('5'+','+myItem[0].text+','+myItem[2].text+','+TownID, TownID[0:2])
else:
print('跳过:ID='+TownID+'page='+villagePage)
print('村庄遍历完成。')
else:
print('ERROR: status_code='+str(page.status_code)) def townFun(CountyID, townPage):
print('townFun> '+CountyID+','+townPage)
page = myRequest(urlPrefix+townPage) # Getting page HTML through request
if(200 == page.status_code):
soup = BeautifulSoup(page.content, 'html.parser') # Parsing content using beautifulsoup links = soup.select("table tbody tr.towntr") # Selecting all of the anchors with titles
first10 = links # Keep only the first 10 anchors
for anchor in first10:
myItem = anchor.select("td a")
if ([] != myItem):
print('4'+','+myItem[0:1][0].text+','+myItem[1:2][0].text+','+CountyID) # Display the innerText of each anchor
Writefile('4'+','+myItem[0:1][0].text+','+myItem[1:2][0].text+','+CountyID, CountyID[0:2])
villageFun(myItem[0:1][0].text, CountyID[0:2]+'/'+CountyID[2:4]+'/'+myItem[0:1][0]['href'])
else:
print('跳过:ID='+CountyID+'page='+townPage) time.sleep(0.5) # 延时,避免太频繁
print('乡镇遍历完成。')
else:
print('ERROR: status_code='+str(page.status_code)) def countyFun(CityID, countyPage):
print('countyFun> '+CityID+','+countyPage)
page = myRequest(urlPrefix+countyPage) # Getting page HTML through request
if(200 == page.status_code):
soup = BeautifulSoup(page.content, 'html.parser') # Parsing content using beautifulsoup links = soup.select("table tbody tr.countytr") # Selecting all of the anchors with titles
first10 = links # Keep only the first 10 anchors
for anchor in first10:
myItem = anchor.select("td a")
if ([] != myItem):
print('3'+','+myItem[0:1][0].text+','+myItem[1:2][0].text+','+CityID) # Display the innerText of each anchor
Writefile('3'+','+myItem[0:1][0].text+','+myItem[1:2][0].text+','+CityID, CityID[0:2])
townFun(myItem[0:1][0].text, CityID[0:2]+'/'+myItem[0:1][0]['href'])
else:
print('跳过:ID='+CityID+'page='+countyPage) time.sleep(0.5) # 延时,避免太频繁
print('县区遍历完成。')
else:
print('ERROR: status_code='+str(page.status_code)) def cityFun(ProvinceID, cityPage):
print('cityFun> '+ProvinceID+','+cityPage)
page = myRequest(urlPrefix+cityPage) # Getting page HTML through request
if(200 == page.status_code):
soup = BeautifulSoup(page.content, 'html.parser') # Parsing content using beautifulsoup links = soup.select("table tbody tr.citytr") # Selecting all of the anchors with titles
first10 = links # Keep only the first 10 anchors
for anchor in first10:
myItem = anchor.select("td a")
if ([] != myItem):
print('2'+','+myItem[0:1][0].text+','+myItem[1:2][0].text+','+ProvinceID) # Display the innerText of each anchor
Writefile('2'+','+myItem[0:1][0].text+','+myItem[1:2][0].text+','+ProvinceID, ProvinceID)
countyFun(myItem[0:1][0].text, myItem[0:1][0]['href'])
else:
print('跳过:ID='+ProvinceID+'page='+cityPage) # time.sleep(0.5) # 延时,避免太频繁
print('城市遍历完成。')
else:
print('ERROR: status_code='+str(page.status_code)) def ProvinceFun():
page = myRequest(urlPrefix+'index.html') # Getting page HTML through request
if(200 == page.status_code):
soup = BeautifulSoup(page.content, 'html.parser') # Parsing content using beautifulsoup links = soup.select("table tbody tr.provincetr td a") # Selecting all of the anchors with titles
first10 = links # Keep only the first 10 anchors
for anchor in first10:
ProvinceID = anchor['href'].rstrip('.html')
print('1'+','+ProvinceID+','+anchor.text+','+'0') # Display the innerText of each anchor
Writefile('1'+','+ProvinceID+','+anchor.text+','+'0', ProvinceID)
cityFun(ProvinceID, anchor['href'])
# time.sleep(3) # 延时,避免太频繁 print('省份遍历完成。')
else:
print('ERROR: status_code='+str(page.status_code)) if __name__ == '__main__':
ProvinceFun()
# cityFun('43', '43.html')
运行完城后控制台回显:
村庄遍历完成。
乡镇遍历完成。
县区遍历完成。
城市遍历完成。
省份遍历完成。
数据结果会写入到txt文本中,示例 webSpiders-Region-43.txt 是这样(文件内容太多,这里只选取文件前几行):
1,43,湖南省,0
2,430100000000,长沙市,43
3,430102000000,芙蓉区,430100000000
4,430102001000,文艺路街道,430102000000
5,430102001001,识字里社区居委会,430102001000
5,430102001002,文艺新村社区居委会,430102001000
5,430102001003,韭菜园社区居委会,430102001000
下一步将这个文件导入到 mysql里面。
新建mysql表:
/*
SQLyog Ultimate v12.09 (64 bit)
MySQL - 8.0.11 : Database - db_xiongzaiqiren
*********************************************************************
*/ /*!40101 SET NAMES utf8 */; /*!40101 SET SQL_MODE=''*/; /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
CREATE DATABASE /*!32312 IF NOT EXISTS*/`db_xiongzaiqiren` /*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci */; USE `db_xiongzaiqiren`; /*Table structure for table `tb_region` */ DROP TABLE IF EXISTS `tb_region`; CREATE TABLE `tb_region` (
`regionID` varchar(36) NOT NULL COMMENT '地区ID',
`regionName` varchar(256) NOT NULL COMMENT '地区名称',
`regionLevel` tinyint(4) NOT NULL DEFAULT '1' COMMENT '地区级别',
`regionParentID` varchar(36) NOT NULL DEFAULT '0' COMMENT '地区上级ID',
`regionIsEnabled` tinyint(4) NOT NULL DEFAULT '1' COMMENT '是否启用',
PRIMARY KEY (`regionID`),
KEY `regionParentID_Level_IsEnabled` (`regionParentID`,`regionLevel`,`regionIsEnabled`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8; /*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
创建数据库,表后,就可以导入txt里的数据了。
LOAD DATA LOCAL INFILE 'D:/pythonWorkspace/webSpiders-Region-43.txt' INTO TABLE db_xiongzaiqiren.tb_region FIELDS TERMINATED BY ',' LINES TERMINATED BY '\r\n'
(regionLevel,regionID,regionName,regionParentID,regionIsEnabled) SET regionIsEnabled=1;
注意:导入语句可能会报错,因为mysql默认没有开启 local_infile ,需要手动设置开启才能导入:
# 服务器端,local_infile默认开启;客户端,local_infile默认关闭,因此用的时候需要打开。
SHOW GLOBAL VARIABLES LIKE 'local_infile';
SET GLOBAL local_infile = 'ON';
等待导入完成,看下受影响的行数,与txt里面的行数对比一下,数据条数是一样的。
【完】
python脚本抓取省市县区乡镇村庄(五级行政区划)的更多相关文章
- php外挂python脚本抓取ajax数据
之前我写过一遍php外挂python脚本处理视频的文章.今天和大家分享下php外挂python实现输入关键字搜索的脚本 首先我们先来分析一波网站: http://www.dzdpw.com/s.php ...
- Python脚本抓取京东手机的配置信息
以下代码是使用python抓取京东小米8手机的配置信息 首先找到小米8商品的链接:https://item.jd.com/7437788.html 然后找到其配置信息的标签,我们找到其配置信息的标签为 ...
- python 处理抓取网页乱码
python 处理抓取网页乱码问题一招鲜 相信用python的人一定在抓取网页时,被编码问题弄晕过一阵 前几天写了一个测试网页的小脚本,并查找是否包含指定的信息. 在html = urllib2. ...
- python Web抓取(一)[没写完]
需要的模块: python web抓取通过: webbrowser:是python自带的,打开浏览器获取指定页面 requests:从因特网上下载文件和网页 Beautiful Soup:解析HTML ...
- python 爬虫抓取心得
quanwei9958 转自 python 爬虫抓取心得分享 urllib.quote('要编码的字符串') 如果你要在url请求里面放入中文,对相应的中文进行编码的话,可以用: urllib.quo ...
- python requests抓取NBA球员数据,pandas进行数据分析,echarts进行可视化 (前言)
python requests抓取NBA球员数据,pandas进行数据分析,echarts进行可视化 (前言) 感觉要总结总结了,希望这次能写个系列文章分享分享心得,和大神们交流交流,提升提升. 因为 ...
- python数据抓取分析(python + mongodb)
分享点干货!!! Python数据抓取分析 编程模块:requests,lxml,pymongo,time,BeautifulSoup 首先获取所有产品的分类网址: def step(): try: ...
- Python爬虫----抓取豆瓣电影Top250
有了上次利用python爬虫抓取糗事百科的经验,这次自己动手写了个爬虫抓取豆瓣电影Top250的简要信息. 1.观察url 首先观察一下网址的结构 http://movie.douban.com/to ...
- Python爬虫抓取东方财富网股票数据并实现MySQL数据库存储
Python爬虫可以说是好玩又好用了.现想利用Python爬取网页股票数据保存到本地csv数据文件中,同时想把股票数据保存到MySQL数据库中.需求有了,剩下的就是实现了. 在开始之前,保证已经安装好 ...
- Python数据抓取技术与实战 pdf
Python数据抓取技术与实战 目录 D11章Python基础1.1Python安装1.2安装pip1.3如何查看帮助1.4D1一个实例1.5文件操作1.6循环1.7异常1.8元组1.9列表1.10字 ...
随机推荐
- .NET 各版本贡献者列表
在微信群里看到有同学对.NET 9的贡献者数量有质疑,.NET 这样的一个全场景的应用开发平台,他的生态是很庞大的,自然一起参与开源贡献的开发者也是很大的,但是很多人都不知道一直有这么一个地址是统计了 ...
- ubuntu 下做反向代理给hyperf使用
使用hyperf的时候发现它监听9501端口,然后这样需要ip+port方式去访问,但是这样对用户而言有点不太友好,如果我们还有域名,可以做一个反向代理避免端口直接写出来. 找了找网上别人写的例子,感 ...
- 高性能计算-雅可比算法MPI通信优化(5)
雅可比算法原理:如下图对方阵非边界元素求上下左右元素的均值,全部计算元素的数值计算完成后更新矩阵,进行下一次迭代. 测试目标:用MPI实现对8*8方阵雅可比算法迭代并行计算,用重复非阻塞的通信方式 # ...
- Java线程池架构2-多线程调度器
http://ifeve.com/java线程池架构2-多线程调度器(scheduledthreadpoolexecutor)/ 在前面介绍了java的多线程的基本原理信息:<Java线程池 ...
- Python:pygame游戏编程之旅一(Hello World)
按照上周计划,今天开始学习pygame,学习资料为http://www.pygame.org/docs/,学习的程序实例为pygame模块自带程序,会在程序中根据自己的理解加入详细注释,并对关键概念做 ...
- Linux禁止某个sudo用户修改root密码
(1) 假设被禁止的sudo用户名为 user (2) 禁止user用户使用passwd命令更改密码(非最终配置) vim /etc/sudoers 加入 user ALL=(root)!/usr/b ...
- web移动端常见问题(一)
1.1物理像素 产生原因:css样式的最小值是1px,不过这个1px只是代表css像素,在高清屏上展示的物理像素要>1(iphone6 1css像素=2物理像素.而iph6p则是1css像素=3 ...
- PLC编程—数据类型
CPU 型号不同,实际的有效数据类型与文中略有不同(大同小异) 数据类型概述 基本数据类型(二进制数.整数.浮点数.定时器.DATE.TOD.LTOD.CHAR.WCHAR) 复杂数据类型(DT.LD ...
- Vite项目无法通过IP+端口的方式访问开发服务
前情 最近要新开一个项目,技术栈由自己安排,于是就想到使用vue3+vite来做,体验一把新技术栈 坑位 vite开发体验极佳,但是在项目完成的时候,想通过本地服务提前发给产品确认UI.交互等细节的时 ...
- DA14531芯片固件逆向系列(1)-固件加载和逆向分析
首发于先知论坛 https://xz.aliyun.com/t/9185 前言 本文介绍逆向DA14531芯片的固件,并介绍一些辅助自动化分析的脚本的实现.DA14531是Dialog公司研制的蓝牙芯 ...