selenium的使用

0x01:selenium的应用场景

有时候我们在网页的源代码里面不能找到在页面中展示的内容,比如这和新闻页面,https://www.toutiao.com/a6729041718571696653/,并不能再源代码里面找到前端展示出来的图片信息,但是右键检查元素却可以定位到元素的位置。这是因为页面展示的数据并不在源代码中,而是经过js加载的,所以并不能直接从源代码中提取出我们需要的数据,这时候,就可以使用selenium打造一个浏览器爬虫。用代码的方式去模拟浏览器操作过程(如:打开浏览器、在输入框里输入文字、回车等),在爬虫方面很有必要。

0x02:准备工作

  • 安装selenium(pip install selenium)
  • 安装chromedriver(一个驱动程序,用以启动chrome浏览器,具体的驱动程序需要对应的驱动,在官网上可以找到下载地址),可以参考上篇随笔。

0x03:基本使用

1 from selenium import webdriver  # 导入模块
2 
3 browser = webdriver.Chrome()  # 创建一个webdriver实例,并选择使用的浏览器
4 browser.get('https://www.baidu.com/')  # 使用get方法访问目标url
5 browser.close()    # 关闭网页

使用chrome浏览器,打开百度,并进行关闭。selenium支持各种常见的浏览器,但chrome功能强大,推荐大家使用这个。

0x04:获取js渲染后的网页源代码

一些经过js渲染的页面,是无法在网页的源代码中找到在前端展示的内容的。这时候,就需要获取到js选然后的网页源代码,以上面那个新闻的url为例,右键检查一下第一张图片元素,复制它的链接,

然后右键查看网页源代码,对这个图片链接进行搜索,可以看到结果为0。

 

用pycharm获取js选然后的源代码在进行搜索,就能够找到这个图片的链接

 代码如下:

1 from selenium import webdriver
2 
3 browser = webdriver.Chrome()
4 browser.get('https://www.toutiao.com/a6729041718571696653/')
5 print(browser.page_source)
6 browser.close()

0x05:元素查找

selenium支持很多元素选取的方法,比如:

  • find_element_by_id             通过标签的id属性,查找元素
  • find_element_by_name     通过标签的name属性查找元素
  • find_element_by_xpath    通过xpath查找元素
  • find_element_by_tag_name  通过元素的标签名称来查找元素。
  • find_element_by_class_name 通过元素的class名查找元素
  • find_element_by_css_selector   通过css查找元素

https://www.cnblogs.com/qingchunjun/p/4208159.html,这篇文章有详细的讲解。

获取到js渲染后的源代码之后,就可以对需要的信息进行提取,比如我们想要提取出上面那个图片的链接,可以先右键检查一下元素。

 发现它在一个class为pgc-img的div标签下的img标签内,可以使用下面代码对这个图片链接进行获取

1 from selenium import webdriver
2 
3 browser = webdriver.Chrome()
4 browser.get('https://www.toutiao.com/a6729041718571696653/')
5 div_image = browser.find_element_by_css_selector('.pgc-img').find_element_by_xpath('./img').get_attribute('src')
6 print(div_image)
7 browser.close()

第五行代码,先使用css查找的方法找到了包含img标签的div标签,后面接着用xpath方法找到了img标签,最后利用get_attribute获取img的src属性,这样就提取出了第一i张图片的链接。

 0x06:多元素查找

上面只查找到了第一张图片的链接,但如果需要获取到所有图片的链接呢?

首先还是对图片元素进行检查,发现每张图片都在一个class为pgc-img的div标签中,那只要获取到这些div标签,就可以进一步获取到每一张图片的链接了。代码如下

 1 from selenium import webdriver
 2 
 3 browser = webdriver.Chrome()
 4 browser.get('https://www.toutiao.com/a6729041718571696653/')
 5 div_image = browser.find_elements_by_css_selector('.pgc-img')
 6 print(div_image)
 7 for img in div_image:
 8     img_url = img.find_element_by_xpath('./img').get_attribute('src')
 9     print(img_url)
10 browser.close()

更改查询方法为find_elements,查找出了所有class为pgc-img的元素,返回对象是一个列表,然后依次对列表里面的元素尽心遍历,查找出每一张图片的链接,结果如图所示

 0x07:页面交互

仅仅抓取页面没有多大卵用,我们真正要做的是做到和页面交互,比如点击,输入等等。那么前提就是要找到页面中的元素。可以利用上面说的那些方法,例如下面有一个表单输入框。

获取了元素之后,下一步当然就是向文本输入内容了,可以利用下面的方法:

element.send_keys("and some", Keys.ARROW_DOWN)

你可以对任何获取到到元素使用 send_keys 方法,就像你在 GMail 里面点击发送键一样。不过这样会导致的结果就是输入的文本不会自动清除。所以输入的文本都会在原来的基础上继续输入。你可以用下面的方法来清除输入文本的内容。

element.clear()

这样,输入的文本就会被清除了

0x08:页面等待

这是非常重要的一部分,现在的网页越来越多采用了 Ajax 技术,这样程序便不能确定何时某个元素完全加载出来了。这会让元素定位困难而且会提高产生 ElementNotVisibleException 的概率。

所以 Selenium 提供了两种等待方式,一种是隐式等待,一种是显式等待。

隐式等待是等待特定的时间,显式等待是指定某一条件直到这个条件成立时继续执行。

显式等待

显式等待指定某个条件,然后设置最长等待时间。如果在这个时间还没有找到元素,那么便会抛出异常了。

 1 from selenium import webdriver
 2 from selenium.webdriver.common.by import By
 3 from selenium.webdriver.support.ui import WebDriverWait
 4 from selenium.webdriver.support import expected_conditions as EC
 5 
 6 driver = webdriver.Chrome()
 7 driver.get("http://somedomain/url_that_delays_loading")
 8 try:
 9     element = WebDriverWait(driver, 10).until(
10         EC.presence_of_element_located((By.ID, "myDynamicElement"))
11     )
12 finally:
13     driver.quit()

程序默认会 500ms 调用一次来查看元素是否已经生成,如果本来元素就是存在的,那么会立即返回。

隐式等待

隐式等待比较简单,就是简单地设置一个等待时间,单位为秒。

from selenium import webdriver

driver = webdriver.Chrome()
driver.implicitly_wait(10) # seconds
driver.get("http://somedomain/url_that_delays_loading")
myDynamicElement = driver.find_element_by_id("myDynamicElement")

文章参考:https://cuiqingcai.com/2599.html

纸上得来终觉浅,绝知此事要躬行。

******************************不积跬步无以至千里。******************************

原文地址:https://www.cnblogs.com/liangshian/p/11433908.html