Python爬虫学习之selenium

概述

在之前,我们学习了使用requests进行爬虫以及使用XPATH等工具提取数据。但是这些方法只能爬取静态网页,无法获取js渲染的数据。后来我们通过分析ajax,使我们可以通过requests来获取数据,这其实也是js渲染的一种情形。但是不是所有的js渲染都使用ajax,这样我们就无法通过ajax来获取数据。而有的页面即便使用ajax获取数据,但是由于加密了很多的参数,很难直接通过ajax获取数据。

为了解决这一问题,我们可以使用Selenium、Splash、Pyppetter、Playwright等库。这些库可以模拟浏览器运行,所看即所得,无需担心js渲染的问题。

准备工作

# pip命令
pip install selenium
# pip3命令
pip3 install selenium
# conda命令
conda install selenium

此外,还可以通过wheel安装,在PyPi下载对应的wheel文件并通过pip命令安装。

pip install 下载的文件名全称

此外,使用selenium需要浏览器配合,本文使用的是chrome,所以需要安装chrome以及 ChromeDriver 驱动。

基本使用

import time
from selenium import webdriver
browser = webdriver.Chrome()
try:
    browser.get('https://www.baidu.com')
    print(browser.page_source)
finally:
    time.sleep(2)
    browser.close()

运行代码后发现,自动弹出来一个Chrome浏览器,打开了百度页面并在控制台输出了该页面的html数据,等待两秒后关闭了浏览器。

如代码所示,我们使用get()方法来请求网页,参数为URL。使用page_source来获取网页数据。

这里使用了Chrome浏览器演示,如果使用其他浏览器,参考一下代码。

from selenium import webdriver

browser = webdriver.Firefox()
browser = webdriver.Edge()
browser = webdriver.Safari()

进阶操作

查找结点

单个节点

如果我们需要使用selenium利用百度来搜索信息,那么需要获取搜索框输入条件,再点击搜索按钮。要完成这些操作,首先需要知道输入框与按钮所在位置。sellenium提供了一系列方法供我们获取想要的节点。如find_element()
在这里插入图片描述
分析源代码可知,搜索输入框的idkwclasss_iptnamewd,因此我们可以通过以下代码获取输入框。

from selenium import webdriver
from selenium.webdriver.common.by import By

browser = webdriver.Chrome()

try:
    browser.get('https://www.baidu.com')
    # 通过id获取
    input1 = browser.find_element(By.ID, 'kw') 
    # 通过class获取
    input2 = browser.find_element(By.CLASS_NAME, 's_ipt')
    # 通过name获取
    input3 = browser.find_element(By.NAME, 'wd')
    # 通过xpath获取
    input4 = browser.find_element(By.XPATH, '//*[@id="kw"]')
    print(input1)
    print(input2)
    print(input3)
    print(input4)
finally:
    browser.close()
<selenium.webdriver.remote.webelement.WebElement (session="a7a4dd9ea41cc319f025623b895bf83c", element="1444d183-6b9d-4eb0-acce-39825ca6337b")>
<selenium.webdriver.remote.webelement.WebElement (session="a7a4dd9ea41cc319f025623b895bf83c", element="1444d183-6b9d-4eb0-acce-39825ca6337b")>
<selenium.webdriver.remote.webelement.WebElement (session="a7a4dd9ea41cc319f025623b895bf83c", element="1444d183-6b9d-4eb0-acce-39825ca6337b")>
<selenium.webdriver.remote.webelement.WebElement (session="a7a4dd9ea41cc319f025623b895bf83c", element="1444d183-6b9d-4eb0-acce-39825ca6337b")>

从结果可以看到,输出的都是同一个节点。

以下列出了所有获取单个节点的By值。

	By.ID
	By.CLASS_NAME
	By.NAME
	By.XPATH
	By.CSS_SELECTOR
    By.LINK_TEXT
    By.PARTIAL_LINK_TEXT
    By.TAG_NAME

多个节点

如果查找的目标有多个,那么使用以上方法只能获取第一个节点。如果要获取所有的节点,使用find_elements() 方法
在这里插入图片描述
如图,我们要获取红线标识位置的节点,可以使用以下代码:

browser = webdriver.Chrome()

try:
    browser.get('https://www.baidu.com')
    alink = browser.find_elements(By.XPATH, '//*[@id="s-top-left"]/a')
    print(alink)
finally:
    browser.close()
[<selenium.webdriver.remote.webelement.WebElement (session="37ae9a9a652b2b7102dc6213c554d58e", element="663d47da-7ad1-49f0-a7ab-4438012b95e6")>, <selenium.webdriver.remote.webelement.WebElement (session="37ae9a9a652b2b7102dc6213c554d58e", element="508d9e09-94dd-4a96-99e8-46af9234ede7")>, <selenium.webdriver.remote.webelement.WebElement (session="37ae9a9a652b2b7102dc6213c554d58e", element="e97c2b07-c13a-4326-afcf-8d0c723642bc")>, <selenium.webdriver.remote.webelement.WebElement (session="37ae9a9a652b2b7102dc6213c554d58e", element="fb62093c-eec0-4821-af4a-966284577f85")>, <selenium.webdriver.remote.webelement.WebElement (session="37ae9a9a652b2b7102dc6213c554d58e", element="75b9c90b-3553-4120-8b8c-48f639a3f453")>, <selenium.webdriver.remote.webelement.WebElement (session="37ae9a9a652b2b7102dc6213c554d58e", element="de58886c-8c11-45c1-bc79-966d42a9f21d")>, <selenium.webdriver.remote.webelement.WebElement (session="37ae9a9a652b2b7102dc6213c554d58e", element="4cecec57-8e34-49b2-8bf4-99b25bce46df")>]

可以看到结果为列表类型,既符合条件的所有节点。
获取节点的By值与获取单节点的By值相同。

节点交互

当我们获取到搜索框的节点时,需要输入我们想要搜索的信息,这时可以使用send_keys()方法实现。
清空文字时使用clear()方法,输入完搜索信息之后点击搜索按钮使用click()方法。代码如下:

browser = webdriver.Chrome()

try:
    browser.get('https://www.baidu.com')
    input1 = browser.find_element(By.ID, 'kw')
    btn = browser.find_element(By.XPATH, '//*[@id="su"]')
    input1.send_keys('汽车')
    btn.click()
finally:
    time.sleep(2)
    browser.close()

执行JavaScript

selenium可以执行js代码,使用execute_script()方法。如下所示,将下拉条滑倒最下面。

browser.execute_script('window.scrollTo(0, document.body.scrollHeight)')

获取节点信息

前面说过,可以使用page_source获取网页源码,之后可以使用解析库来提取信息。而selenium也提供了相关的方法与属性来获取节点信息。

获取节点属性 get_attrbute()

browser = webdriver.Chrome()

try:
    browser.get('https://www.baidu.com')
    alink = browser.find_elements(By.XPATH, '//*[@id="s-top-left"]/a')
    for al in alink:
        print(al.get_attribute("href"))
finally:
    browser.close()
http://news.baidu.com/
https://www.hao123.com/?src=from_pc
http://map.baidu.com/
http://tieba.baidu.com/
https://haokan.baidu.com/?sfrom=baidu-top
http://image.baidu.com/
https://pan.baidu.com/?from=1026962h

这里使用 get_attribute()方法获取所有的a节点的href属性。如果需要其他属性值,只需要传入属性名即可。

获取节点文本值 text

browser = webdriver.Chrome()

try:
    browser.get('https://www.baidu.com')
    alink = browser.find_elements(By.XPATH, '//*[@id="s-top-left"]/a')
    for al in alink:
        # print(al.get_attribute("href"))
        print(al.text)
finally:
    browser.close()
新闻
hao123
地图
贴吧
视频
图片
网盘

对于文本,直接使用text属性即可。

获取id、位置、标签名、大小

browser = webdriver.Chrome()

try:
    browser.get('https://www.baidu.com')
    alink = browser.find_elements(By.XPATH, '//*[@id="s-top-left"]/a')
    for al in alink:
        # print(al.get_attribute("href"))
        # print(al.text)
        print(al.id)
        print(al.location)
        print(al.tag_name)
        print(al.size)
finally:
    browser.close()
# 这里只显示第一个a节点的内容
574bed25-08ae-46bd-b59b-5c661a95bf64
{'x': 24, 'y': 19}
a
{'height': 23, 'width': 26}

如代码所示,id属性可以获取节点id,location可以获取节点在页面的相对位置,tag_name获取节点的标签名,size获取节点的大小。

总结

到这里,基本上就可以使用selenium来完成一些简单的操作了,可以获取想要的数据,快来试一试吧!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值