Python 爬虫之Selenium终极绝招

2019-06-26 18:35:49 浏览数 (1)

遇到动态渲染的问题时,如果无法提取ajax接口,或者无法破解token值计算,那我们只能使用终极绝招,Selenium测试框架。只是它性能低,不适合服务器部署,但活人不能让尿憋死,这是无奈的选择。

这里简单解释一下什么是Selenium,它其实是一个网站前端压力测试框架,更通俗的说,它能直接操作浏览器,试想一下,网页是在浏览器里面加载的,如果我们能用代码操控浏览器,那我们想要爬取什么数据不能通过浏览器获取?无所不爬!

环境准备

安装 selenium

代码语言:javascript复制
1 python -m pip install selenium

安装浏览器驱动 想要操作浏览器,当然需要浏览器驱动了,这些驱动是浏览器官方提供的,如果你用的小众浏览器,那建议你赶紧装一个谷歌浏览器Chrome,它是目前最流畅最好用的。

Selenium支持的其他浏览器都有其对应的驱动器

下载驱动后,将解压得到的可执行程序路径添加到本地PATH环境变量中,或者将可执行程序拷贝到python根目录下。

代码示例

以下设置了无头浏览器,即无界面后台运行,可以节省GPU开销,但我个人经验,使用无头模式,爬取的速度反而更慢,大家可以把设置无头模式的那两行代码注释后自测一下速度,请谨慎选择。

代码语言:javascript复制
 1 from selenium.webdriver.chrome.options import Options
 2 from selenium import webdriver
 3 from selenium.webdriver.common.by import By
 4
 5 chrome_options = Options()
 6 # 设置无头浏览器
 7 chrome_options.add_argument('--headless')
 8 chrome_options.add_argument('--disable-gpu')
 9 # 设置代理
10 chrome_options.add_argument("--proxy-server=http://127.0.0.1:1080")
11
12 # 创建浏览器实例
13 browser = webdriver.Chrome(chrome_options=chrome_options)
14 # 打开网页
15 browser.get("http://www.solidfiles.com/v/nYdm5gVQ2DRyY")
16 # 查找元素
17 browser.find_elements(By.XPATH, '//*/form/button')[0].submit()

示例2 注意,这里还能通过browser.page_source获取经过selenium动态渲染之后的网页,然后再使用我们之前介绍过的bs4来解析元素

代码语言:javascript复制
 1 import cookie_handle as ch
 2 from selenium.webdriver.chrome.options import Options
 3 from selenium import webdriver
 4 from bs4 import BeautifulSoup
 5
 6 # 处理自动登录时,可将已登录的Cookies值复制到此处
 7 cookies = ""
 8
 9 chrome_options = Options()
10 # 设置无头浏览器
11 # chrome_options.add_argument('--headless')
12 # chrome_options.add_argument('--disable-gpu')
13
14 browser = webdriver.Chrome(chrome_options=chrome_options)
15 browser.get("https://www.tianyancha.com/search/ocD")
16
17 for opt in ch.getCookies(cookies):
18    browser.add_cookie(opt)
19
20 # 我们还可通过selenium动态渲染之后,再将html网页交给BeautifulSoup解析
21 def get_content(url):
22    browser.get(url)
23
24    bsObj = BeautifulSoup(browser.page_source,"lxml")
25    for line in bsObj.select(".name"):
26        print(line.text)
27
28 get_content("https://www.tianyancha.com/search/ocD")
29 for i in range(2,10):
30    url = "https://www.tianyancha.com/search/ocD/p%d" % i
31    get_content(url)

我们可以通过抓包,将已经登录的Cookies 字符串复制出来,然后使用以下方法将Cookies解析成selenium需要的格式

代码语言:javascript复制
1 def getCookies(text):
2    result = []
3    for line in text.split(";"):
4        k ,v = line.strip().split("=")
5        result.append({"name":k,"value":v})
6
7    return result

参考文档:https://selenium-python-zh.readthedocs.io/en/latest/index.html

基本文档

要定位一个页面中的元素有多中策略和方法。你可以根据实际情况选择其中最为合适的。Selenium为定位页面元素提供了下面的这些方法:

  • find_element_by_id(使用id)
  • find_element_by_name(使用name属性值)
  • find_element_by_xpath(使用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(使用CSS选择器)

要定位多个元素,除了通过id进行定位,只需将element s(这些元素将会以列表的形式返回)

  • find_elements_by_name(使用name属性值)
  • find_elements_by_xpath(使用XPath)
  • find_elements_by_link_text(使用显示文本)
  • find_elements_by_partial_link_text(使用超链接文本)
  • find_elements_by_tag_name(使用标签名)
  • find_elements_by_class_name(使用类名)
  • find_elements_by_css_selector(使用CSS选择器)

除了上面的通用方法外,在一个页面对象进行访问操作的时候还有两个非常有用的私有方法:find_elementfind_elements

代码示例:

代码语言:javascript复制
1 from selenium.webdriver.common.by import By
2
3 driver.find_element(By.XPATH, '//button[text()="Some text"]')
4 driver.find_elements(By.XPATH, '//button')

By类可用的属性如下:

代码语言:javascript复制
1 ID = "id"
2 XPATH = "xpath"
3 LINK_TEXT = "link text"
4 PARTIAL_LINK_TEXT = "partial link text"
5 NAME = "name"
6 TAG_NAME = "tag name"
7 CLASS_NAME = "class name"
8 CSS_SELECTOR = "css selector"

实战

http://jandan.net/ooxx 也是一个妹子图网,但是该网站是动态渲染的,使用我们第一章的方法无法爬取该网站的图片,大家可以使用本章学习的内容尝试爬取该网站。

0 人点赞