爬虫目的:获取国内外爆炸事件的相关信息
数据来源:中华人民共和国应急管理部 点击查看数据源
所需字段:国家、时间、行业类型、爆炸事件、死亡受伤人数、爆炸原因、来源网址
工具:Python+selenium+正则表达式
selenium + chromedriver爬取前的环境配置
selenium的安装直接使用pip命令,Chromedriver下载的版本应和谷歌浏览器的版本对应(也可以是火狐、EI浏览器)。
Chromedriver下载地址:http://npm.taobao.org/mirrors/chromedriver/
在Windows中,右键此电脑——>属性——>高级系统设置——>环境变量——>系统环境变量——>Path——>编辑,然后找到谷歌浏览器的文件位置(在快捷方式右键-打开文件位置),并把下载好的Chromedriver.exe放入路径下,并复制路径添加进环境变量中(通过新建添加新的环境变量)。
运行以下python代码,若没有报错则证明Chromedriver配置成功
from selenium import webdriver
driver = webdriver.Chromedriver()
driver.get('http:\\www.baidu.com')
若仍继续报错,则考虑使用以下代码:
from selenium import webdriver
driver = webdriver.Chromedriver(executable_path='chromedriver的路径')
driver.get('http://www.baidu.com')
若出现报错AttributeError: module ‘selenium.webdriver‘ has no attribute ‘Chromedriver问题时,考虑将代码中的Chromedriver改为Chrome,即代码为:
from selenium import webdriver
driver = webdriver.Chrome(executable_path='chromedriver的路径')
driver.get('http://www.baidu.com')
网页解析及代码
若是谷歌浏览器,右键选择“检查”,进入开发者模式,要提取的字段可以用下图所示方法寻找。
webdriver是模拟浏览器方式进行爬取,核心是元素定位,可以通过标签、类名等方式,具体介绍可以看官网链接:Selenium-Python中文文档(查找元素)
- find_element_by_id
- find_element_by_name
- find_element_by_xpath
- find_element_by_link_text
- find_element_by_partial_link_text
- find_element_by_tag_name
- find_element_by_class_name
- find_element_by_css_selector
对于xpath,可以选中后右击——>Copy——>Copy XPath,具体如下图所示:
获取单页链接
from selenium import webdriver
driver = webdriver.Chrome(executable_path='C:\\Program Files\\Google\\Chrome\\Application\\chromedriver.exe')
driver.get('https://www.mem.gov.cn/fw/jsxx/')
for i in range(1, 8, 2):
for j in range(1, 6):
link = driver.find_element_by_xpath('//*[@id="page_body"]/div[4]/div[4]/div[' + str(i) + ']/ul/li['+ str(j) + ']/a').get_attribute('href')
print(link)
获取翻页链接
from selenium import webdriver
import time
start_url = "https://www.mem.gov.cn/fw/jsxx/"
driver = webdriver.Chrome(executable_path='C:\\Program Files\\Google\\Chrome\\Application\\chromedriver.exe')
def get_content():
time.sleep(2)
item = {}
next_page = driver.find_element_by_link_text('下一页').get_attribute('href')
#li_list = driver.find_elements_by_xpath('//*[@id="page_body"]/div[4]/div[4]/div[1]/ul/li')
for i in range(1, 8, 2):
for j in range(1, 6):
item['link'] = driver.find_element_by_xpath('//*[@id="page_body"]/div[4]/div[4]/div[' + str(i) + ']/ul/li['+ str(j) + ']/a').get_attribute('href')
print(item)
save_csv(item)
return next_page
def save_csv(item):
str = ','.join([i for i in item.values()])
with open('E:\\科研\\spider.csv','a',encoding='utf-8') as f:
f.write(str)
f.write('\n')
def run():
driver.get(start_url)
while True:
next_page = get_content()
driver.get(next_page)
run()
补充:对于for i in range(1, 8, 2): for j in range(1, 6)的两层循环,因为我是根据XPath进行定位的,所以需要找到每个元素的XPath规律,也可以通过classname等其他方式定位,具体看上面链接就可以啦
链接内容存到文件中
import pandas as pd
data = pd.read_csv(r"E:\科研\spider_link.csv",header=None)
from selenium import webdriver
driver = webdriver.Chrome(executable_path='C:\\Program Files\\Google\\Chrome\\Application\\chromedriver.exe')
for i in range(len(data)):
driver.get(data[0][i])
#需要再加一个对标题的过滤,去掉不是爆炸事件的网页
text = driver.find_element_by_class_name('TRS_Editor').text
file = "E:\\科研\\爆炸事件文本\\text" + str(i) + ".txt"
with open(file,"w", encoding='utf-8') as f:
f.write(text) # 自带文件关闭功能,不需要再写f.close()
正则表达式
时间
import re
text = text.replace("年", "-").replace("月", "-").replace("日", " ").replace("/", "-").strip()
output = re.findall(r"(\d{4}-\d{1,2}-\d{1,2})",text)
output
爆炸事件
import re
output = re.findall(r"(?= ).*?公司",text)
output
死亡受伤人数
import re
output = re.findall(r"(?=造成).*?死亡",text)
output
爆炸原因
import re
output = re.findall(r"(?<=:).*?。",text)
output
主要采用的正则表达式为python正则表达式匹配指定字符开始和指定字符结束
a开始b结束的匹配: a.*?b
限制是一行的开头和末尾: ^a.*?b$
不包含a,b 只匹配中间a和b中间的内容 : (?<=A).*?(?=B)
正则表达式的用法具体可参考 Python 正则表达式