Selenium安装与使用

1. Selenium 介绍

有时候,网站动态加载的内容经过加密后,我们是无法看懂密文的,但是JavaScript可以看懂,所以如果能一行一行读JavaScript代码,理论上可以读取任何动态加载的页面内容。但问题是大型网站的JavaScript动辄上万行,还经过混淆,肉眼去读几乎不可完成。

大家会发现,在Chrome的“检查”中,Elements选项卡下,我们可以看到被动态加载的内容,说明Chrome检查此时显示的内容,已经是被解析了以后的内容。如果我们能够获得这个被解析的内容,那就能获取到被加密的内容。

这种情况下,就需要使用Selenium来模拟浏览器解析JavaScript,我们再爬取被解析以后的代码。

2. Selenium安装

方式一:

使用pip安装Selenium:

pip install selenium

安装情况如图所示:
安装selenium

方式二:

(非必需)下载Selenium的jar包:https://docs.seleniumhq.org/download/

Selenium 的jar包只有在需要使用Selenium的remote WebDriver的时候才有用。这里的remote WebDriver不一定是远程使用,因为有时候如果要处理的网页比较多的话,每次都开一个WebDriver是非常消耗时间的,因此可以在本地或者远程搭建一个WebDriver来节约时间。

方式三:

下载ChromeDriver:https://sites.google.com/a/chromium.org/chromedriver/downloads

下载下来的压缩包解压以后是一个可执行文件。Selenium需要使用的WebDriver才能处理网页,这里的WebDriver我们可以理解为一个小型的浏览器。它可以是Firefox,可以是Chrome也可以是PhantomJS. 其中前两者是有界面的,在处理网页的时候,会弹出一个浏览器窗口。而PhantomJS是没有界面的,这个适合在服务器上来使用。

1. 初始化webdriver

from selenium import webdriver
driver = webdriver.Chrome('./chromedriver')
driver.get("https://v.youku.com/v_show/id_XMTY2NTk5ODAwMA==.html?from=y1.3-idx-beta-1519-23042.223465.3-3")

这里需要初始化 selenium 的WebDriver, 由于我们使用的是Chrome,所以需要调用:

webdriver.Chrome('ChromeDriver的路径')

其中,ChromeDriver的路径如果和代码在一起,那么就需要写为:./chromedriver

在OS X下的这个ChromeDriver没有后缀名,而如果大家是在Windows下面,ChromeDriver是一个exe的可执行程序,大家就需要把 .exe 加上。另外需要特别注意斜杠的问题,在Windows下面路径中的反斜杠需要使用特殊处理,例如:

webdriver.Chrome(r'D:\test\chromedriver.exe')

注意这里的“r”不能少。

2. 等待信息出现

由于被动态加载的内容会延迟出现,因此我们需要等待它出现以后才开始抓取。需要使用到WebDriverWait,By 和 expected_conditions

from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

WebDriverWait(driver, 300).until(EC.presence_of_element_located((By.CLASS_NAME, "con")))

WebDriverWait会阻塞程序的运行,并每0.5秒检查一次网页源代码,看我们需要的内容是否已经出现。如果没有出现就继续等待。

在上面的代码中,设定了超时时间为300秒。在300秒内,如果有某个元素出现,那么就解除阻塞,继续运行后面的代码;如果等待的内容始终不出现,那么就会抛出一个超时的Exception。

我们来看一下:

EC.presence_of_element_located((By.CLASS_NAME, "con"))

这里的EC其实就是 expected_conditions,也就是期望的条件。Python接近英语的语法让我们可以非常轻松的看懂这一段代码:

期望的条件.元素出现
而这里的元素就是一个class=”con”的元素。

这里除了指定class以外,还可以指定很多其他的属性,例如:

By.ID
By.NAME
By.XPATH

通过元组的形式传递给presence_of_element_located方法。

在网页中寻找我们需要的内容,可以使用类似与Beautiful Soup4 的语法:

element = driver.find_element_by_id("passwd-id") #如果有多个符合条件的,返回第一个
element = driver.find_element_by_name("passwd") #如果有多个符合条件的,返回第一个
element_list = driver.find_elements_by_id("passwd-id") #以列表形式返回所有的符合条件的element
element_list = driver.find_elements_by_name("passwd") #以列表形式返回所有的符合条件的element

也可以使用XPath:

element = driver.find_element_by_xpath("//input[@id='passwd-id']") #如果有多个符合条件的,返回第一个
element = driver.find_element_by_xpath("//input[@id='passwd-id']") #以列表形式返回所有的符合条件的element

但是有一点需要特别注意:这些名字都是find_element开头的,因此他们返回的都是element对象。这些方法他们的目的是寻找element,而不是提取里面的值。

所以当我们使用find_element_by_xpath的时候,不能使用text()这个语句。如果我们想获取里面的文本信息,需要在获取到element以后,再使用element.text。例如:

comment = driver.find_elements_by_xpath('//p[starts-with(@id, "content_")]')
for each in comment:
    print(each.text)

更多Selenium的使用方法,可以参阅它的Python文档:https://selenium-python.readthedocs.io/getting-started.html

Leave a Comment