社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

python3 爬虫第二步Selenium 使用简单的方式抓取复杂的页面信息

1_bit • 3 年前 • 341 次点击  

Selenium 简介

该系列专栏上一篇爬虫文章 点击这里

网站复杂度增加,爬虫编写的方式也会随着增加。使用Selenium 可以通过简单的方式抓取复杂的网站页面,得到想要的信息。

Selenium 是操作浏览器进行自动化,例如自动化访问网站,点击按钮,进行信息采集,对比直接使用bs4 抓取信息,Selenium的抓取速度是有很大缺陷,但是如果抓取页面不多,页面复杂时,使用Selenium是个不错的选择。
本文将会使用Selenium 进行一些简单的抓取,想要深入学习Selenium 可以查看我之前写过的 《selenium3 底层剖析》 两篇。

Selenium 使用注意

在使用 Selenium前需要安装 Selenium,使用pip命令,安装如下:

pip install selenium
  • 1

安装完成 Selenium 还需要下载一个驱动。

  • 谷歌浏览器驱动:驱动版本需要对应浏览器版本,不同的浏览器使用对应不同版本的驱动,点击 下载
  • 如果是使用火狐浏览器,查看火狐浏览器版本,点击
    GitHub火狐驱动下载地址
    下载(英文不好的同学右键一键翻译即可,每个版本都有对应浏览器版本的使用说明,看清楚下载即可)

作者的环境说明如下:

  • 操作系统:Windows7 SP1 64
  • python 版本:3.7.7
  • 浏览器:谷歌浏览器
  • 浏览器版本: 80.0.3987 (64 位)

下载好驱动后, 必须把驱动给配置到系统环境,或者丢到你python的根目录下。

正式开始

首先在代码中引入 selenium

from selenium import webdriver
  • 1

可能有些读者没有把驱动配置到环境中,接下来我们可以指定驱动的位置:

driver = webdriver.Chrome(executable_path=r'F:\python\dr\chromedriver_win32\chromedriver.exe')
  • 1

以上代码调用Chrome 方法并且配置驱动地址( 这里使用 executable_path 指定驱动地址 )为“ F:\python\dr\chromedriver_win32\chromedriver.exe ”,这时就可以指定了驱动位置,也可以不用配置到环境了。
这时运行一下代码,查看是否会打开一个浏览器。
在这里插入图片描述
这时将会成功打开谷歌浏览器。
这时 driver 变量为浏览器对象,通过 driver 操作浏览器,使用 get 方法可以访问一个网址。这时我们可以访问 百度。代码如下:

from selenium import webdriver
driver = webdriver.Chrome(executable_path=r'F:\python\dr\chromedriver_win32\chromedriver.exe')
driver.get("http://baidu.com")
  • 1
  • 2
  • 3

成功打开百度搜索界面:
在这里插入图片描述
例如我们想搜索爬虫,使用selenium实现自动搜索。首先需要了解的一个函数为 find_element_by_id,该函数可以通过id 找到界面元素。在html中,大部分有特殊作用的元素会赋予一个id,搜索时需要填写的是百度搜索关键字的文本框,将鼠标移动到文本框,对准文本框点击鼠标右键,点击检查可以查看元素。
在这里插入图片描述
点击检查后将会出现一个源码窗口:
在这里插入图片描述
其中input为文本框元素,id的值是 kw。
这时得知了文本框的id 值为kw,可以使用 find_element_by_id 函数给予id值,找到元素对象,并且可以操作元素对象进行增删操作。由于 find_element_by_id 是浏览器对象的方法,使用浏览器对象调用,代码如下:

input = driver.find_element_by_id('kw')
  • 1

这时还差向该对象输入要搜索的值。使用 send_keys 方法可以自动键入值,编写如下:

input.send_keys("爬虫")
  • 1

其中input是刚刚获取的元素对象。这时运行代码查看效果:
在这里插入图片描述
这时自动键入了要搜索的关键帧“爬虫”。接下来根据之前的步骤,应该找到 百度一下 按钮的id,随后点击即可。通过相同的流程,得到百度一下 按钮的html代码:

<input type="submit" id="su" value="百度一下" class="bg s_btn">
  • 1

得到id为su,使用 find_element_by_id 得到元素对象:

enter = driver.find_element_by_id('su')
  • 1

该元素调用click方法即可进行点击:

enter.click()
  • 1

最终代码如下:

from selenium import


    
 webdriver
driver = webdriver.Chrome(executable_path=r'F:\python\dr\chromedriver_win32\chromedriver.exe')
driver.get("https://www.baidu.com/")
input = driver.find_element_by_id('kw')
input.send_keys("爬虫")
enter = driver.find_element_by_id('su')
enter.click()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

运行结果如下:
在这里插入图片描述

信息获取

能够进行自动打开了,下一步接下来需要做的就是获取搜索的信息。
在这里需要介绍一个知识点 xpath,我们可以理解xpath就像 x,y坐标一样的东西,用于html或者说xml语言中的定位,表示一个位置。简单的使用并不需要去学习它如何编写,因为从浏览器中我们可以直接得到。

如下图,我们右键搜索出来了信息第一个标题,点击检查后会出现源代码。在源代码中右键,选择Copy之后点击Copy XPath,这时我们就把当前这个元素的XPath获取了。
在这里插入图片描述
获取到了XPath后,复制到文本框,查看是如下形式:

//*[@id="3001"]/div[1]/h3/a
  • 1

在这里注意,理论上每一个页面的第一行结果都将会是该XPath,并不需要每一页都去获取,但也有情况不一致的时候,具体情况得具体分析。
我们简单实用XPath不需要了解过多,接下来可以使用 find_element_by_xpath 获取到当前元素对象。

res_element=driver.find_element_by_xpath('//*[@id="3001"]/div[1]/h3/a')
  • 1

获取到元素对象后,可以调用该元素对象的text属性获取到当前文本值:

print(res_element.text)
  • 1

完整代码如下:

from selenium import webdriver
import time
driver = webdriver.Chrome(executable_path=r'F:\python\dr\chromedriver_win32\chromedriver.exe')
driver.get("https://www.baidu.com/")
input = driver.find_element_by_id('kw')
input.send_keys("爬虫")
enter = driver.find_element_by_id('su')
enter.click()
time.sleep(2)

res_element=driver.find_element_by_xpath('//*[@id="3001"]/div[1]/h3/a')
print(res_element.text)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

以上代码中 time.sleep(2) 是为了等待点击搜索后页面加载数据,不然会获取不到对象。
结果如下:
在这里插入图片描述
以上省略了浏览器自动打开并搜索内容的过程,直接查看了结果。
那么我们每一页都获取第一个结果,这时只需要自动点击下一页后获取即可。
首先得到下一页按钮的元素对象:
在这里插入图片描述
复制XPath值为:

//*[@id="page"]/div/a[10]
  • 1

则获取下一页对象并且点击跳转的代码为:

nextbtn_element=driver.find_element_by_xpath('//*[@id="page"]/div/a[10]')
nextbtn_element.click()
  • 1
  • 2

运行后发现成功跳转到第二页,接下来可以继续获取搜索栏的第一个对象,可以使用循环实现这个过程,我们设定去搜索前10页的所有第一个结果值,这时所有代码可以写为:

from selenium 


    
import webdriver
import time
driver = webdriver.Chrome(executable_path=r'F:\python\dr\chromedriver_win32\chromedriver.exe')
driver.get("https://www.baidu.com/")
input = driver.find_element_by_id('kw')
input.send_keys("爬虫")
enter = driver.find_element_by_id('su')
enter.click()
time.sleep(2)


for _ in range(10):
    res_element=driver.find_element_by_xpath('//*[@id="3001"]/div[1]/h3/a')
    print(res_element.text)
    nextbtn_element=driver.find_element_by_xpath('//*[@id="page"]/div/a[10]')
    nextbtn_element.click()
    time.sleep(2)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

for 循环最下面的停止2秒是为了点击下一页后数据进行加载的等待时间。
运行后,结果发现报错:
在这里插入图片描述
我们的12行为:

res_element=driver.find_element_by_xpath('//*[@id="3001"]/div[1]/h3/a')
  • 1

那么在这里应该是 //*[@id="3001"]/div[1]/h3/a 定位错误,没有找到该定位的元素。我们查看第一页、第二页、第三页的第一条结果进行对比:

第一页://*[@id="3001"]/div[1]/h3/a
第二页://*[@id="11"]/h3/a
第三页://*[@id="21"]/h3/a
第四页://*[@id="31"]/h3/a
第五页://*[@id="41"]/h3/a
  • 1
  • 2
  • 3
  • 4
  • 5

从以上数据得知,只有第一页的XPath 不同,其它的XPath都遵循从11-21-31-41 每一页加10的规律。
并且发现下一页按钮的 XPath也发生了改变,变成了:

//*[@id="page"]/div/a[11]
  • 1

完整代码如下:

from selenium import webdriver
import time
#请求网页
driver = webdriver.Chrome(executable_path=r'F:\python\dr\chromedriver_win32\chromedriver.exe')
driver.get("https://www.baidu.com/")
#输入并且搜索
input = driver.find_element_by_id('kw')
input.send_keys("爬虫")
enter = driver.find_element_by_id('su')
enter.click()
#等待2秒加载
time.sleep(2)



    
#获取第一个结果并且点击下一页
res_element=driver.find_element_by_xpath('//*[@id="3001"]/div[1]/h3/a')
print(res_element.text)
nextbtn_element=driver.find_element_by_xpath('//*[@id="page"]/div/a[10]')
nextbtn_element.click()
time.sleep(2)

#设置一个变量start
start=1
#循环点击下一页 并且获取第一条数据
for _ in range(10):
    start+=10
    xpath_val=r'//*[@id="'+str(start)+r'"]/h3/a' #//*[@id="11"]/h3/a
    res_element=driver.find_element_by_xpath(xpath_val)
    print(res_element.text)
    nextbtn_element=driver.find_element_by_xpath('//*[@id="page"]/div/a[11]')#//*[@id="page"]/div/a[11] //*[@id="page"]/div/a[11]
    nextbtn_element.click()
    time.sleep(2)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

以上代码中:

from selenium import webdriver
import time
#请求网页
driver = webdriver.Chrome(executable_path=r'F:\python\dr\chromedriver_win32\chromedriver.exe')
driver.get("https://www.baidu.com/")
#输入并且搜索
input = driver.find_element_by_id('kw')
input.send_keys("爬虫")
enter = driver.find_element_by_id('su')
enter.click()
#等待2秒加载
time.sleep(2)
#获取第一个结果并且点击下一页
res_element=driver.find_element_by_xpath('//*[@id="3001"]/div[1]/h3/a')
print(res_element.text)
nextbtn_element=driver.find_element_by_xpath('//*[@id="page"]/div/a[10]')
nextbtn_element.click()
time.sleep(2)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

为之前的代码,新增循环为遍历下一页以及获取第一个结果:

   #设置一个变量start
start=1
#循环点击下一页 并且获取第一条数据
for _ in range(10):
    start+=10
    xpath_val=r'//*[@id="'+str(start)+r'"]/h3/a' #//*[@id="11"]/h3/a
    res_element=driver.find_element_by_xpath(xpath_val)
    print(res_element.text)
    nextbtn_element=driver.


    
find_element_by_xpath('//*[@id="page"]/div/a[11]')#//*[@id="page"]/div/a[11] //*[@id="page"]/div/a[11]
    nextbtn_element.click()
    time.sleep(2)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

首先设置一个start,因为第二页是 XPath 中变化的值为11-21-31…,设置一个变量为1,每次加10即可,所以在循环中,第一句为:

start+=10
  • 1

由于XPath的值其它字符串没变化,所以整一条XPath语句可以写为:

xpath_val=r'//*[@id="'+str(start)+r'"]/h3/a'
  • 1

之后传入xpath函数获取元素即可:

res_element=driver.find_element_by_xpath(xpath_val)
  • 1

接下来的语句都没有太大变化,只有按钮的XPath有变化,所以更改了XPath。其它代码均和之前的相似。最终运行结果如下:
在这里插入图片描述
由于有一些其它信息所以打码了,这就是一个简单的selenium爬虫编写方式,之后将会持续更新爬虫系列。

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/71130
 
341 次点击