Python+Selenium 爬虫详解

简介: Python+Selenium 爬虫详解

前言

在实现爬虫时,解决反爬问题是我们经常要面对的。如果使用传统的 Requests 模块进行爬虫,我们要详细研究请求方法、请求参数等内容。而如果我们使用 Selenium 进行爬虫,我们只需要关注用户的操作,我们可以模拟人操作浏览器。这样我们就可以减少很多应付反爬的内容。

文章内容如下:

  1. 下载 Web Driver
  2. Selenium 的简单使用
  3. Selenium 中的选择器
  4. Selenium 中的动作链
  5. 使用 Selenium 实现自动登录
  6. 使用 Selenium 实现图片爬虫

下载 WebDriver

Selenium 原本是用来进行网站自动化测试的工具,后来人们发现了 Selenium 在爬虫方面的潜力,因此它也能胜任一些爬虫工作。

在我们使用 Selenium 时,会打开一个浏览器,然后模拟人鼠标和键盘操作,因此这种方式的爬虫难以被察觉。

Selenium 支持许多浏览器,本次 Chat 将使用 Chrome 浏览器作为例子。首先我们需要下载浏览器驱动,下载地址如下:

http://chromedriver.storage.googleapis.com/index.html

下载驱动时需要对应你的浏览器版本,比如我的版本如下:

在这里插入图片描述

可以看到版本是 87,因此我们需要找到如下链接:

在这里插入图片描述

选择对应版本的浏览器驱动,放在 Python 的根目录下即可。

接下来我们还需要下载 Selenium 模块,只需要执行下面语句就好了:

pip install selenium

下面我们看看如何使用。

Selenium 的简单使用

下载好驱动后,我们就可以开始使用了。如果你把驱动放在 Python 的根目录下,那你可以直接运行下面的代码:

from selenium.webdriver import Chrome
# 创建浏览器(浏览器驱动)
chrome = Chrome()
# 打开百度的页面
chrome.get('https://www.baidu.com')

运行后程序会帮我们自动打开浏览器,并打开百度的页面。我们可以看一下每句代码的意思。

首先我们需要导入需要使用的浏览器驱动类:

from selenium.webdriver import Chrome

因为要使用的是 Chrome,所有这里导入 Chrome。我们可以创建一个浏览器对象(驱动),任何调用 get 方法,传入页面 url。

我们还可以找到百度的搜索框进行搜索:

from selenium.webdriver import Chrome
# 导入 selenium 中的键
from selenium.webdriver.common.keys import Keys
# 创建一个浏览器
chrome = Chrome()
# 打开百度页面
chrome.get('https://www.baidu.com')
# 找到输入框并输入关键词,再按 ENTER
chrome.find_element_by_xpath('//*[@id="kw"]').send_keys('星际穿越', Keys.ENTER)

上面的代码在后面我们会详细说,我们先看一下效果:

在这里插入图片描述

可以看到我们打开了一个页面。但是我们是怎么找到元素的呢?其中 find\_element\_by\_xpath 是寻找元素的操作,而 send_keys 对元素的具体操作。下面我们先来看看寻找元素的操作。

Selenium 中的选择器

在 Selenium 中有很多种选择器,我们可以通过 css、tag、xpath 等属性进行选择。在上面的例子种我们就是通过 xpath 进行选择。

下面我们看看具体代码吧:

from selenium.webdriver import Chrome
from selenium.webdriver.common.keys import Keys
chrome = Chrome()
chrome.get('https://www.baidu.com')
# 通过 xpath 查找元素
chrome.find_element_by_xpath('xpath')
# 通过 id 查找元素
chrome.find_element_by_id('id')
# 通过 class_name 查找元素
chrome.find_element_by_class_name('class')
# 通过标签名查找数据
chrome.find_element_by_tag_name('tag')
# 通过 name 属性查找数据
chrome.find_element_by_name('name')

上面我们没有实际查找内容,只是写了一些方法。我们只需要在网页源码中找到需要查找的元素的属性就可以调用相应的方法。

比如下面我们查看一下百度输入框的属性:

在这里插入图片描述

可以看到输入框的 class 是 s_ipt,这样我们就可以通过 class 找到输入框:

from selenium.webdriver import Chrome
from selenium.webdriver.common.keys import Keys
chrome = Chrome()
chrome.get('https://www.baidu.com')
# 通过类名找到输入框
chrome.find_element_by_class_name('s_ipt').send_keys('星际穿越', Keys.ENTER)

可以看到这次也成功了:

在这里插入图片描述

我们还可以通过下面的方法找到元素列表:

from selenium.webdriver import Chrome
from selenium.webdriver.common.keys import Keys
chrome = Chrome()
chrome.get('https://www.baidu.com')

chrome.find_elements_by_xpath('xpath')
chrome.find_elements_by_id('id')
chrome.find_elements_by_class_name('class')
chrome.find_elements_by_tag_name('tag')
chrome.find_elements_by_name('name')

这次我们只是将方法名加了个 s,但是这次返回的是元素集合,我们可以通过循环拿到单个元素的内容,比如下面的代码:

from selenium.webdriver import Chrome
from selenium.webdriver.common.keys import Keys
chrome = Chrome()
chrome.get('https://www.baidu.com')

imgs = chrome.find_elements_by_tag_name('img')
for img in imgs:
    print(img.get_attribute('src'))

我们找到百度页面的所有 img 标签,然后把 img 的 src 输出:

https://dss0.bdstatic.com/5aV1bjqh_Q23odCf/static/superman/img/topnav/baiduyun@2x-e0be79e69e.png
https://dss0.bdstatic.com/5aV1bjqh_Q23odCf/static/superman/img/topnav/zhidao@2x-e9b427ecc4.png
https://dss0.bdstatic.com/5aV1bjqh_Q23odCf/static/superman/img/topnav/baike@2x-1fe3db7fa6.png
https://dss0.bdstatic.com/5aV1bjqh_Q23odCf/static/superman/img/topnav/tupian@2x-482fc011fc.png
https://dss0.bdstatic.com/5aV1bjqh_Q23odCf/static/superman/img/topnav/baobaozhidao@2x-af409f9dbe.png
https://dss0.bdstatic.com/5aV1bjqh_Q23odCf/static/superman/img/topnav/wenku@2x-f3aba893c1.png
https://dss0.bdstatic.com/5aV1bjqh_Q23odCf/static/superman/img/topnav/jingyan@2x-e53eac48cb.png
https://dss0.bdstatic.com/5aV1bjqh_Q23odCf/static/superman/img/topnav/yinyue@2x-c18adacacb.png
https://www.baidu.com/img/fddong_e2dd633ee46695630e60156c91cda80a.gif
https://www.baidu.com/img/fddong_e2dd633ee46695630e60156c91cda80a.gif
https://www.baidu.com/img/flexible/logo/pc/result.png
https://www.baidu.com/img/flexible/logo/pc/result@2.png
https://www.baidu.com/img/flexible/logo/pc/peak-result.png
https://dss0.bdstatic.com/5aV1bjqh_Q23odCf/static/superman/img/qrcode/qrcode@2x-daf987ad02.png
https://dss0.bdstatic.com/5aV1bjqh_Q23odCf/static/superman/img/qrcode/qrcode-hover@2x-f9b106a848.png

Process finished with exit code 0

可以看到效果达到了。不过还有许多选择方式,这里就不细讲了。

Selenium 中的动作链

动作链就是模仿人的动作,比如你要登录需要先输入用户名,然后输入密码,然后再点击登录按钮。这就是一系列动作,我们可以通过动作链来实现这些动作,下面我们看看一个简单的例子:

from selenium.webdriver import Chrome
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.action_chains import ActionChains
chrome = Chrome()
chrome.get('https://www.baidu.com')
# 创建动作链
ac = ActionChains(chrome)
# 找到要操作的标签
input = chrome.find_element_by_class_name('s_ipt')
ac.move_to_element(input).send_keys('星际穿越', Keys.ENTER).perform()

我们先创建了一个 ActionChians(动作链),我们需要将浏览器传入,表示对浏览器进行的一些列动作。

然后调用 move\_to\_element 方法,把光标移动到 input 框。该方法需要一个元素对象,因此在移动光标前我们先通过 class\_name 找到了 input 框,再把 input 框传入 move\_to_element 方法。

然后再输入内容,并点击 ENTER 键。这正好对应了我们搜索时的操作。

最后我们需要执行这些操作,这需要我们调用 perform 方法。动作链中还有其它一些操作,我们可以简单看一下:

# 点击元素
ac.click()
# 双击元素
ac.double_click()
# 点击鼠标右键
ac.context_click()
# 按住鼠标不放
ac.click_hold()
# 释放鼠标左键
ac.release()
# 将元素拖拽然后松开
ac.drag_and_drop()

从上面的方法可以看出,我们很多操作都需要先找到元素,然后再执行。当然我们可以选择使用动作连来实现对浏览器的操作,也可以使用元素自身的方法实现对浏览器的操作,比如:

# 找到元素
elem = chrome.find_element_by_class_name('name')
# 点击元素
elem.click()

现在我们知道了通过动作链实现浏览器的一些操作,我们实现一个简单的爬虫。

使用 Selenium 实现自动登录

首先我们需要知道登录的具体步骤,我们可以看一下登录页面:

在这里插入图片描述

可以看到并没有直接显示用户名密码的 input 框,这个时候就需要我们自己找了。在二维码下方可以看到一个账号密码登录的字样,我们点击之后发现了输入框,然后后面的操作就很简单了:

  1. 找到了“账号密码登录”,并点击
  2. 找到用户名密码的 input 框,并输入用户名密码
  3. 点击登录(或者点击回车)

下面我们用动作连来实现一个模拟登录的操作:

from selenium.webdriver import Chrome
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.action_chains import ActionChains
chrome = Chrome()
# 打开 QQ 空间
chrome.get('https://qzone.qq.com/')
# 切换 iframe
chrome.switch_to.frame('login_frame')
# 点击登录
chrome.find_element_by_xpath('//*[@id="switcher_plogin"]').click()

# 找到用户名和密码输入框
chrome.find_element_by_xpath('//*[@id="u"]').send_keys('qq 号')
chrome.find_element_by_xpath('//*[@id="p"]').send_keys('密码', Keys.ENTER)

如果你运行上面的代码会发现找不到元素 //*[@id="switcher_plogin"],我们可以查看一下源码:

在这里插入图片描述

会发现二维码部分被包含在一个 iframe 标签里面,因此我们是无法直接找到元素的,我们需要先切换到 iframe 中才能找到我们需要的元素,于是我将代码修改为下面:

from selenium.webdriver import Chrome
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.action_chains import ActionChains
chrome = Chrome()
# 打开 QQ 空间
chrome.get('https://qzone.qq.com/')
# 切换 iframe
chrome.switch_to.frame('login_frame')
# 点击登录
chrome.find_element_by_xpath('//*[@id="switcher_plogin"]').click()

# 找到用户名和密码输入框
chrome.find_element_by_xpath('//*[@id="u"]').send_keys('qq 号')
chrome.find_element_by_xpath('//*[@id="p"]').send_keys('密码', Keys.ENTER)

会发现这次我们成功实现了自动登录。

使用 Selenium 实现图片爬虫

下面我们再来看一个爬虫,我们使用 Selenium 实现图片爬虫。其实图片爬虫不是 Selenium 擅长的部分,因为 Selenium 是基于浏览器的爬虫。因此会打开浏览器,当我们爬取的页面较多时 Selenium 的效率就比较低。但是我们还是可以学习一下。

我们可以把上面通过 tag_name 查找的代码修改一下:

import requests
from selenium.webdriver import Chrome
chrome = Chrome()
# 打开 QQ 空间
chrome.get('https://www.fabiaoqing.com/')
imgs = chrome.find_elements_by_tag_name('img')
name = 0
for img in imgs:
    url = img.get_attribute('src')
    try:
        with open('img/%s.jpg' % name, 'wb') as f:
            f.write(requests.get(url).content)
    except Exception as e:
        pass
    name += 1

这里我们借助了 requests 模块,需要额外安装:

pip install requests

我们使用 request 发送请求,获取图片的二进制内容,然后写入到一个文件当中。对于 requests 的操作,我们可以详细看一下:

import requests
resp = requests.get('url')
resp.content

我们首先导入了 requests 模块,然后调用 get 方法,传入要请求的 url,然后服务器会给我们返回一个响应信息。其中 resp.content 就是响应的二进制数据,因为是图片文件,因此我们需要使用二进制写入的模式打开文件:

with open('1.jpg', 'wb') as f

运行成功后就会发现本地多了许多图片,这就是我们爬取的图片。当然我们上面的操作非常简单,只是单纯寻找 img 标签,对于更复杂的网站,我们可以分析元素结构然后找到自己需要的标签并获取 url 进行爬取。

目录
相关文章
|
14天前
|
数据采集 存储 API
网络爬虫与数据采集:使用Python自动化获取网页数据
【4月更文挑战第12天】本文介绍了Python网络爬虫的基础知识,包括网络爬虫概念(请求网页、解析、存储数据和处理异常)和Python常用的爬虫库requests(发送HTTP请求)与BeautifulSoup(解析HTML)。通过基本流程示例展示了如何导入库、发送请求、解析网页、提取数据、存储数据及处理异常。还提到了Python爬虫的实际应用,如获取新闻数据和商品信息。
|
18天前
|
数据采集 Python
【python】爬虫-西安医学院-校长信箱
本文以西安医学院-校长信箱为基础来展示爬虫案例。来介绍python爬虫。
【python】爬虫-西安医学院-校长信箱
|
24天前
|
数据采集 安全 Python
python并发编程:Python实现生产者消费者爬虫
python并发编程:Python实现生产者消费者爬虫
25 0
python并发编程:Python实现生产者消费者爬虫
|
4天前
|
前端开发 测试技术 C++
Python自动化测试面试:unittest、pytest与Selenium详解
【4月更文挑战第19天】本文聚焦Python自动化测试面试,重点讨论unittest、pytest和Selenium三大框架。unittest涉及断言、TestSuite和覆盖率报告;易错点包括测试代码冗余和异常处理。pytest涵盖fixtures、参数化测试和插件系统,要注意避免过度依赖unittest特性。Selenium的核心是WebDriver操作、等待策略和测试报告生成,强调智能等待和元素定位策略。掌握这些关键点将有助于提升面试表现。
18 0
|
4天前
|
数据采集 存储 JSON
Python爬虫面试:requests、BeautifulSoup与Scrapy详解
【4月更文挑战第19天】本文聚焦于Python爬虫面试中的核心库——requests、BeautifulSoup和Scrapy。讲解了它们的常见问题、易错点及应对策略。对于requests,强调了异常处理、代理设置和请求重试;BeautifulSoup部分提到选择器使用、动态内容处理和解析效率优化;而Scrapy则关注项目架构、数据存储和分布式爬虫。通过实例代码,帮助读者深化理解并提升面试表现。
13 0
|
7天前
|
数据采集 JavaScript 前端开发
使用Python打造爬虫程序之破茧而出:Python爬虫遭遇反爬虫机制及应对策略
【4月更文挑战第19天】本文探讨了Python爬虫应对反爬虫机制的策略。常见的反爬虫机制包括User-Agent检测、IP限制、动态加载内容、验证码验证和Cookie跟踪。应对策略包括设置合理User-Agent、使用代理IP、处理动态加载内容、验证码识别及维护Cookie。此外,还提到高级策略如降低请求频率、模拟人类行为、分布式爬虫和学习网站规则。开发者需不断学习新策略,同时遵守规则和法律法规,确保爬虫的稳定性和合法性。
|
13天前
|
Web App开发 测试技术 网络安全
|
19天前
|
数据采集 存储 前端开发
Python爬虫如何快速入门
写了几篇网络爬虫的博文后,有网友留言问Python爬虫如何入门?今天就来了解一下什么是爬虫,如何快速的上手Python爬虫。
21 0
|
搜索推荐 Java 测试技术
selenium,python自动化之通过id找元素
selenium,python自动化之通过id找元素
selenium,python自动化之通过id找元素
|
搜索推荐 Java 测试技术
selenium,python自动化之通过class_name找元素
selenium,python自动化之通过class_name找元素
selenium,python自动化之通过class_name找元素

热门文章

最新文章