一、设定搜索条件
from selenium import webdriver
import time
options = webdriver.ChromeOptions()
"""
使用IP代理跳过反爬策略频繁爬取会触发验证码机制,ip:port为指定的IP及端口号
"""
options.add_argument('--proxy-server=http://ip:port')
options.add_argument("--headless")
options.add_argument('--disable-gpu')
driver = webdriver.Chrome(options=options)
browser = webdriver.Chrome()
try:
browser.get("http://wenshu.court.gov.cn/list/list")
time.sleep(2)
# 获取搜索框
inputs = browser.find_element_by_id("gover_search_key")
# 获取搜索按钮
submit = browser.find_element_by_id("btnSearch")
# 清空搜索框
inputs.clear()
# 搜索框输入“债权债务”
inputs.send_keys('债权债务')
time.sleep(5)
# 点击搜索
submit.click()
finally:
#关闭浏览器
browser.quit()
二、爬取列表页信息及详情页信息
from selenium import webdriver
from fake_useragent import UserAgent
from bs4 import BeautifulSoup
from selenium.webdriver.support.wait import WebDriverWait
import time
options = webdriver.ChromeOptions()
# 隐藏"Chrome正在受到自动软件的控制"
options.add_argument('disable-infobars')
# 使用IP代理跳过反爬策略,频繁爬取会触发验证码机制,下面只是示范格式
options.add_argument('--proxy-server=http://127.0.0.1:80')
# 设置selenium不加载图片,提高爬取效率
prefs = {"profile.managed_default_content_settings.images": 2}
options.add_experimental_option("prefs", prefs)
# 修改请求头,伪装浏览器型号
options.add_argument('user-agent='+UserAgent().random)
# 无浏览器模式,无浏览器模式无法定位元素
# options.add_argument("--headless")
# options.add_argument('--disable-gpu')
# 采用上述配置
browser = webdriver.Chrome(options=options)
# 将浏览器窗口最大化
# browser.maximize_window()
# 指定浏览器窗口大小
browser.set_window_size(560, 400)
try:
browser.get("http://wenshu.court.gov.cn/list/list/?sorttype=1&number=QTRAA7GV&"
"guid=1db11f43-6b7a-ea82131d-ae7a449e89d2&conditions="
"searchWord+QWJS+++%E5%85%A8%E6%96%87%E6%A3%80%E7%B4%A2:%E5%80%BA%E6%9D%83%E5%80%BA%E5%8A%A1")
# 获取当前列表页
index_windows = browser.current_window_handle
for i in range(20):
# 给浏览器足够时间加载页面,也是为了防止触发反爬策略
time.sleep(30)
# 每0.5秒检测一次列表页是否加载出数据,加载完成,点击进入详情页
WebDriverWait(browser, 50, poll_frequency=0.5).until(lambda browser: browser.find_element_by_id("dataItem1"))
# 获取列表页每个子项信息,并点开链接
for j in range(1, 11):
# 获取每个列表子项
item = browser.find_element_by_css_selector('#dataItem'+str(j)+' a')
# 文书标签
types = browser.find_element_by_css_selector('#dataItem'+str(j)+' .label').text
# 文书标题
title = item.text
# 文书副标题
sub_title = browser.find_element_by_css_selector('#dataItem'+str(j)+' .fymc').text
# 裁判理由
reason = browser.find_element_by_css_selector('#dataItem'+str(j)+' .wszy').text
doc = {'types': types, 'title': title, 'sub_title': sub_title, 'reason': reason}
print(doc)
time.sleep(10)
# 模拟点击,进入详情页
item.click()
# 删除所有的cookie
browser.delete_all_cookies()
all_handles = browser.window_handles
browser.switch_to.window(index_windows)
# 遍历所有浏览器窗口,关闭详情页,仅保留列表页,再进行下一页操作
for handle in all_handles:
if handle != index_windows:
# 切换至详情页
browser.switch_to.window(handle)
soup = BeautifulSoup(browser.page_source, 'html.parser')
# 获取文书内容
Content = soup.find('div', id='Content').get_text()
print(Content)
# 获取隐藏信息
hidCaseInfo = soup.find('input', {'id': 'hidCaseInfo'}).get('value')
print(hidCaseInfo)
# 获取“下一页”元素,点击进入下一页
WebDriverWait(browser, 50, poll_frequency=0.5).until(lambda browser:
browser.find_element_by_css_selector(".next"))
browser.find_element_by_css_selector(".next").click()
finally:
now = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))
filename = now+'.png'
# 浏览器截屏
browser.get_screenshot_as_file(filename)
browser.quit()
三、总结
相较于之前用过的phpquerylist爬取网页,python+selenium可以用来爬取js渲染的数据,而phpquerylist只能用于爬取网页dom元素,也就是说如果数据是页面加载后,采用js请求接口返回的数据渲染的,那就无能为力了。但是针对这种请求,我们也可以直接分析接口地址,直接请求。
裁判文书网也是这种js请求接口返回的数据,但不同的是它的参数都是经过加密的,同一个详情页,链接地址可能是不一样的。这种情况下,必须暴力破解它的加密方式才能通过接口请求到数据。
在对加密方式无能为力的情况下,对数据量要求也不高的时候,python+selenium是一个折中的选择吧,这种爬虫方式,即使对方网站修改了加密方式,也可以继续爬取,因为它是完全模拟人的行为在访问网页。但是如果页面元素发生了变动,也需要同步地更新爬虫代码。
破解加密后,可以通过request模块请求接口地址,获取数据的效率可以得到极大的提升。
关于爬虫效率问题,多线程、分布式是两个很好的方向,有待继续学习,在2018年的最后一天,对自己说一声,加油,对诸君道一声,共勉!