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 进行爬取。

目录
相关文章
|
3天前
|
数据采集 存储 XML
构建高效的Python爬虫系统
【9月更文挑战第30天】在数据驱动的时代,掌握如何快速高效地获取网络信息变得至关重要。本文将引导读者了解如何构建一个高效的Python爬虫系统,从基础概念出发,逐步深入到高级技巧和最佳实践。我们将探索如何使用Python的强大库如BeautifulSoup和Scrapy,以及如何应对反爬措施和提升爬取效率的策略。无论你是初学者还是有经验的开发者,这篇文章都将为你提供宝贵的知识和技能,帮助你在信息收集的海洋中航行得更远、更深。
15 6
|
1天前
|
数据采集 数据挖掘 数据处理
Python中实现简单爬虫并处理数据
【9月更文挑战第31天】本文将引导读者理解如何通过Python创建一个简单的网络爬虫,并展示如何处理爬取的数据。我们将讨论爬虫的基本原理、使用requests和BeautifulSoup库进行网页抓取的方法,以及如何使用pandas对数据进行清洗和分析。文章旨在为初学者提供一个易于理解的实践指南,帮助他们快速掌握网络数据抓取的基本技能。
11 3
|
5天前
|
数据采集 Python
天天基金数据的Python爬虫
天天基金数据的Python爬虫
20 3
|
5天前
|
数据采集 JSON 数据格式
Python:南京地铁每日客流数据的爬虫实现
Python:南京地铁每日客流数据的爬虫实现
15 1
|
5天前
|
数据采集 Python
Python:某市公交线路站点的爬虫实现
Python:某市公交线路站点的爬虫实现
|
5天前
|
数据采集 网络协议 调度
Python爬虫策略分析4
Python爬虫策略分析4
18 1
|
5天前
|
数据采集 前端开发 Python
Python爬虫策略分析3
Python爬虫策略分析3
|
5天前
|
数据采集 Python
Python爬虫策略分析1
Python爬虫策略分析1
|
3天前
|
数据采集 Linux 网络安全
python 爬虫遇到的aiohttp证书错误解决办法
python 爬虫遇到的aiohttp证书错误解决办法
16 0
|
5天前
|
数据采集 JSON 前端开发
Python爬虫策略分析2
Python爬虫策略分析2
下一篇
无影云桌面