Python爬取——国家统计局省份加城市 并写入数据库

数据库设计

数据库省份表(province)
在这里插入图片描述
城市表(city)
在这里插入图片描述
Python代码

import requests
from lxml import etree
import pymysql
from fake_useragent import UserAgent
#请求方法
def request(param):
    url = 'http://www.stats.gov.cn/tjsj/tjbz/tjyqhdmhcxhfdm/2018/'
    url = url + param
    # 伪装
    ua = UserAgent()
    headers = {'User-Agent':ua.random}
    response = requests.get(url=url,headers=headers)
    # 获取字符集编码
    response.encoding = response.apparent_encoding
    data = response.text
    # 将源码数据加载到数据对象中
    data = etree.HTML(data)
    return data


param = 'index.html'
data = request(param)
#省份数据列表
province_data = []
#城市数据列表
city_data = []
province_list = data.xpath('//tr[@class="provincetr"]/td')
for provinceli in province_list:
    province = provinceli.xpath('./a/text()')[0]
    #获取省份下一级链接
    next_src =provinceli.xpath('./a/@href')[0]
    #获取省份id值,为城市表的外键
    province_id = next_src.split('.')[0]
    print('-----------' + province + '爬取成功,进入城市爬取-----------')

    #对省份数据进行切片、数据转换处理
    #       思路
    #       1、先创建一个空的列表
    #       2、根据省份表的需要,将省份id、名字添加到空的列表中
    #       3、将添加过后的列表转化为元组
    #       4、将转换后的元祖添加到全局列表中(列表名称为:级别 + _data)
    pro_data = []
    pro_data.append(province_id)
    pro_data.append(province)
    pro_data = tuple(pro_data)
    province_data.append(pro_data)


    #进入城市查询
    data = request(next_src)
    city_list = data.xpath('//tr[@class="citytr"]')
    for cityli in city_list:
        city_name = cityli.xpath('./td[2]/a/text()')[0]
        # 获取城市下一级链接
        city_next_src = cityli.xpath('./td[1]/a/@href')[0]
        # 获取城市id
        city_id = cityli.xpath('./td[1]/a/text()')[0]
        print(city_name + city_next_src + city_id + '   爬取成功!!')


        # 对城市数据进行切片、数据转换处理
        #       思路
        #       1、先创建一个空的列表
        #       2、根据城市表的需要,将城市id、名字、上一级省份ID(省份,城市这两个页面比较特殊)添加到空的列表中
        #       3、将添加过后的列表转化为元组
        #       4、将转换后的元祖添加到全局列表中(列表名称为:级别 + _data)

        #---cit_data 的名字要与全局city_data区分开,起名有点相似    cit_data != city_data
        cit_data = []
        up_id = city_next_src.split('/')[0]  #城市表上一级id(外键)
        new_src = city_next_src.split('/')[1] #城市下一级
        cit_data.append(city_id)
        cit_data.append(city_name)
        cit_data.append(up_id)
        # print(cit_data)
        cit_data = tuple(cit_data)
        city_data.append(cit_data)
print(province_data)

#连接数据库
connecion =pymysql.connect (
    host='localhost',  # 数据库地址
    user='root',  # 数据库用户名
    password='19981216',  # 数据库密码
    db='china',  # 数据库名称
)

cursor = connecion.cursor()
province_sql = 'insert into province(province_id,province_name) values (%s,%s)'
city_sql = 'insert into city(city_id,city_name,up_id) values (%s,%s,%s)'

cursor.executemany(province_sql,province_data)
connecion.commit()
print(cursor.rowcount)
cursor.executemany(city_sql,city_data)
connecion.commit()
print(cursor.rowcount)
cursor.close()
connecion.close()

总结:

  • 利用xpath解析的时候,一定要把路径写正确。一直以为省份和城市的数据解析路径一样,然后就一直解析不出来
  • 使用了fake_useragent浏览器伪装库,但是因为这是换了浏览器的user-Agent,ip地址并没有更换,所以当你多次运行程序时,会受到反爬虫机制的影响,抓不到数据。
  • 同步爬取,效率低,数据量小的时候感觉不出来,把国家统计局中的信息爬取到village的时候,你就会知道有多慢了(亲自测试过一个省份的所有下级信息)。

推荐一个大佬的反爬虫机制策略:
https://blog.csdn.net/ITBigGod/article/details/103248172

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章