前言
本文记录抓取民政部数据时,出现的坑。主要抓取页面中县以上行政区划代码链接的具体内容。本文章仅用于笔者记录学习过程,请遵守相关法律法规,严禁用于非法途径。若读者因此作出任何危害网络安全的行为,后果自负,与笔者无关。
确定数据来源
首先需要确认县以上行政区划代码链接是否在响应中,右键查看网页源代码,在页面中搜索“2020年11月份县以上行政区划代码”,发现存在该关键字,可以确定能够从网页响应中获取需要的数据。
接着,在超链接“2020年11月份县以上行政区划代码”上右键检查,查看所指向的url地址,如下图所示:
分析数据
点击url地址,发现页面跳转后的地址与点击的url地址不符
怀疑在点击页面后,触发JS脚本链接重定向,于是将页面的响应打印输出,观察响应中是否存在页面跳转后的url地址,最终发现是有的,于是利用xpath表达式对真正的url地址进行提取。
编写程序
以下代码是根据上文的分析,利用requests库实现的;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
| ''' 使用requests库爬取民政部数据 ''' import requests from fake_useragent import UserAgent from lxml import etree
class MzbSpider: def __init__(self): self.url = 'https://www.mca.gov.cn/article/sj/xzqh/2020/'
def get_headers(self): headers = {'User-Agent': UserAgent().random} return headers
def get_html(self, url): headers = self.get_headers() html = requests.get(url=url, headers=headers).text return html
def parse_data(self, url): html = self.get_html(url) eobj = etree.HTML(html) city = eobj.xpath('//tr[@height="19"]') for item in city: li = {} city_id = item.xpath('./td[2]//text()')[0] city_name = item.xpath('./td[3]/text()')[0] li[city_id] = city_name print(li)
def parse_html(self): html = self.get_html(self.url) eobj = etree.HTML(html) link = eobj.xpath('//ul[@class="alist_ul"]/table//tr[1]//a/@href') href = 'https://www.mca.gov.cn' + link[0] html = self.get_html(href) target = etree.HTML(html).xpath('//body/script[1]/text()')[0].strip() target_href = target.split('"')[1] self.parse_data(target_href)
if __name__ == '__main__': spider = MzbSpider() spider.parse_html()
|
以下代码是利用selenium实现的,利用selenium无需考虑网站链接重定向的问题,此外以下代码还利用redis数据库做了增量爬虫;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| ''' 使用selenium民政部数据爬取 ''' import sys from selenium import webdriver import redis import time from hashlib import md5
class MzbSpider: def __init__(self): options = webdriver.ChromeOptions() options.add_argument('--headless') self.driver = webdriver.Chrome(options=options) self.driver.get('http://www.mca.gov.cn/article/sj/xzqh/2020/') self.r = redis.Redis(host='localhost', port=6379)
def md5_href(self, href): m = md5() m.update(href.encode()) return m.hexdigest()
def parse_html(self): a = self.driver.find_element_by_partial_link_text('县以上行政区划代码') href = a.get_attribute('href') if self.r.sadd('mzbSpider', self.md5_href(href)) == 0: sys.exit('结束') a.click() time.sleep(1) all_handles = self.driver.window_handles self.driver.switch_to.window(all_handles[1]) info = self.driver.find_elements_by_xpath('//tr[@height="19"]') for item in info: info_dic = {} li = item.text.split() info_dic['code'] = li[0] info_dic['name'] = li[1] print(info_dic)
if __name__ == '__main__': spider = MzbSpider() spider.parse_html()
|