用Python获取最新的省、市、县
因为数据库的数据信息建于12年,很多地区三级关系和名称都跟不上了,让我手动一个个添加又觉得麻烦,怎么说我也是一个码农而不是文员,上代码:
#! /usr/bin/env python
# coding=utf-8
import requests
from lxml import etree
import sys
import xlwt
import re
import copy
import json
from lxml.html import fromstring,tostring
import HTMLParser
import re#初始化
reload(sys)
sys.setdefaultencoding('utf8')#根据网页源码,匹配并返回源码内指定的整个a标签
def get_content(data,str,num=999):content = []
data1 = etree.HTML(data).xpath(str)
i = 0
for x in data1:
i += 1
#如果大于指定的数,就跳出循环
if i>num:
continue;
content.append(HTMLParser.HTMLParser().unescape(tostring(x)))#删除第一次获取数据时,多余的第一第二个数据
if num == 36:
del content[0],content[0]return content
#根据网站首页的编码,获取各个省的链接,并且返回三级地区的所有a标签
def get_url(url):
#获取数据
data = requests.get(url,stream=True).content
#获取整个a标签,注意匹配法则
contents = get_content(data,"//div/ul/li/a",36)
# print contents
# exit()
#获取一级地区编码,用于拼接链接
data1 = etree.HTML(data).xpath("//div/ul/li/a/@href")
i = 0
key = []
for x in data1:
i += 1
if i>36:
continue;
#匹配值符合地区编码规则的内容写入
if len(x) == 18:
key.append(x[2:14]) #获取地区链接#根据省编码获取三级编码和地区名称
# url2s = url+key[0]+'.htm'
# data2s = requests.get(url2s,stream=True).content #调用拼接的链接 获取数据
# content2 = get_content(data2s,"//div/table/tr/td/a")
# contents += content2
for htm in key:
url2s = url+htm+'.htm'
print url2s
data2s = requests.get(url2s,stream=True).content #调用拼接的链接 获取数据
content2 = get_content(data2s,"//div/table/tr/td/a")
contents += content2return contents
#根据a标签list数据,进行正则表达式匹配获取需要的地区编码和地区名称,并写入文件存储
def set_data(data):
dictData = {}
for x in data:
key = re.search(r"\d+\d+\d+", x, re.M)
val = re.search(r"[^\x00-\xff]+", x, re.M)
#生成字典
dictData[key.group()] = val.group()
#print key.group()+"-"+val.group()
#对字典进行排序,排序后得到的是list类型的数据,而不是字典
NewData = sorted(dictData.items(), key=lambda e:e[0])
# 如果filename不存在会自动创建, 'w'表示写数据,写之前会清空文件中的原有数据!
filename = "area.txt"
with open(filename,'w') as f:
for d in NewData:
# print json.dumps(d, ensure_ascii=False, encoding='UTF-8')
print d[0]+"-"+d[1]
f.write(d[0]+"-"+d[1]+"\n")
#执行处理方法
url = 'http://www.xzqy.net/'
#测试数据
dataGG = [u'<a href="./110000000000.htm">\u5317\u4eac</a>', u'<a href="./120000000000.htm">\u5929\u6d25</a>',
u'<a href="./310000000000.htm">\u4e0a\u6d77</a>', u'<a href="./500000000000.htm">\u91cd\u5e86</a>',
u'<a href="./370000000000.htm">\u5c71\u4e1c</a>', u'<a href="./140000000000.htm">\u5c71\u897f</a>',
u'<a href="./130000000000.htm">\u6cb3\u5317</a>', u'<a href="./410000000000.htm">\u6cb3\u5357</a>',
u'<a href="./430000000000.htm">\u6e56\u5357</a>', u'<a href="./420000000000.htm">\u6e56\u5317</a>',
u'<a href="./320000000000.htm">\u6c5f\u82cf</a>', u'<a href="./330000000000.htm">\u6d59\u6c5f</a>',
u'<a href="./340000000000.htm">\u5b89\u5fbd</a>', u'<a href="./350000000000.htm">\u798f\u5efa</a>',
u'<a href="./220000000000.htm">\u5409\u6797</a>', u'<a href="./210000000000.htm">\u8fbd\u5b81</a>',
u'<a href="./230000000000.htm">\u9ed1\u9f99\u6c5f</a>', u'<a href="./360000000000.htm">\u6c5f\u897f</a>',
u'<a href="./610000000000.htm">\u9655\u897f</a>', u'<a href="./460000000000.htm">\u6d77\u5357</a>',
u'<a href="./510000000000.htm">\u56db\u5ddd</a>', u'<a href="./520000000000.htm">\u8d35\u5dde</a>',
u'<a href="./530000000000.htm">\u4e91\u5357</a>', u'<a href="./620000000000.htm">\u7518\u8083</a>',
u'<a href="./810000000000.htm">\u9999\u6e2f</a>', u'<a href="./820000000000.htm">\u6fb3\u95e8</a>',
u'<a href="./710000000000.htm">\u53f0\u6e7e</a>', u'<a href="./440000000000.htm">\u5e7f\u4e1c</a>',
u'<a href="./450000000000.htm">\u5e7f\u897f</a>', u'<a href="./540000000000.htm">\u897f\u85cf</a>',
u'<a href="./630000000000.htm">\u9752\u6d77</a>', u'<a href="./640000000000.htm">\u5b81\u590f</a>',
u'<a href="./650000000000.htm">\u65b0\u7586</a>', u'<a href="./150000000000.htm">\u5185\u8499\u53e4</a>']dataAll = get_url(url)
set_data(dataAll)
exit()
这个爬虫是第二版,第一版因为效率问题让我很不满意,所有遗留了很多引用包,可以忽略。
在这次编码过程,也学习了很多Python的内容:
1,字典是关联数组,不能使用下标来调用值,排序后返回的是二维的list数据类型
2,用xpath获取整个a标签时,需要xpath参数的定位规则
3,数据在控制台输出的时候,中文显示的是十六进制,查看是否是因为 整个list输出的原因,如二维list循环输出的是一维list,所有还需要进行更精确的指定到中文的节点,即:list显示十六进制,要精确到末尾接单才会正常显示。当然也可以用json模块的方法进行处理输出,注释代码内有写。
因为兴趣而随便写写,觉得好玩,便分享出来