侧边栏壁纸
博主头像
聆尘风博主等级

欲买桂花同载酒,终不似,少年游

  • 累计撰写 56 篇文章
  • 累计创建 17 个标签
  • 累计收到 2 条评论

目 录CONTENT

文章目录

selenium

聆尘风
2023-11-01 / 0 评论 / 0 点赞 / 18 阅读 / 16950 字

# selenium入门

## 1. selenium概述

我们在抓取一些普通网页的时候requests基本上是可以满足的. 但是, 如果遇到一些特殊的网站. 它的数据是经过加密的. 但是呢, 浏览器却能够正常显示出来. 那我们通过requests抓取到的内容可能就不是我们想要的结果了. 例如,

![image-20210125173604985](https://s2.loli.net/2023/07/17/5d8SikpLDfYgZ3R.png)

电影票房数据. 在浏览器上看的时候是正常的. 那么按照之前的逻辑. 我们只需要看看数据是通过哪个请求拿到的就可以进行模拟请求了. 但是!

![image-20210125173719899](image-20210125173719899.png)

数据找到了. 接着看"预览"吧

![image-20210125173744598](https://s2.loli.net/2023/07/17/EYx7P3dkCDy9ZRo.png)

我们发现这个数据是经过加密算法的. 这就头疼了. 直接通过requests拿到这些内容必须要解密才能看到真实数据. 但是该网站采用的加密方式又不是那么容易破解. 此时, 各位想想如果我能通过我的程序直接调用浏览器. 让浏览器去解密这些内容. 我们直接拿结果岂不妙哉. 哎~这就引出了我们本章要重点讲解的selenium了. 它可以完美解决上述问题

简单介绍一下selenium, 它本身是一个自动化测试的工具. 可以启动一个全新的浏览器.并从浏览器中提取到你想要的内容. 随着各种网站的反爬机制的出现. selenium越来越受到各位爬sir的喜爱. selenium最大的缺点其实就一个, 慢! 你想啊. 他要启动一个第三方的软件(浏览器), 并且还要等待浏览器把数据渲染完毕. 这个过程必然是很耗时的. 所以它慢.

接下来, 我们来聊聊selenium如何安装和使用.

就像其他第三方库一样, selenium直接用pip就可以安装了

```python

pip install selenium

```

但是呢, 它与其他库不同的地方是他要启动你电脑上的浏览器, 这就需要一个驱动程序来辅助.

chrome驱动地址:https://npm.taobao.org/mirrors/chromedriver

这里推荐用chrome浏览器. 其他浏览器的驱动请自行百度.

![image-20210125174618013](https://s2.loli.net/2023/07/17/cUeM1YRa93oi82z.png)

![image-20210125174658971](https://s2.loli.net/2023/07/17/6M2nU5kzH4iwC3V.png)

根据你电脑的不同自行选择吧. win64选win32即可.

然后关键的来了. 把你下载的浏览器驱动放在程序所在的文件夹. 或者放到python解释器所在的文件夹. 两种二选其一.

![image-20210125174915946](https://s2.loli.net/2023/07/17/aWZbzwM8dFEqJpN.png)

或者

![image-20210125175328245](https://s2.loli.net/2023/07/17/qVO9ItLFdYM1wA4.png)

OK~ 前期准备工作完毕. 上代码看看, selenium是个什么鬼

```python

from selenium.webdriver import Chrome # 导入谷歌浏览器的类

# 创建浏览器对象

web = Chrome(executable_path="chromedriver") # 如果你的浏览器驱动放在了项目里.

# web = Chrome() # 如果你的浏览器驱动放在了解释器文件夹

web.get("http://www.baidu.com") # 输入网址

print(web.title) # 打印title

```

运行一下你会发现神奇的事情发生了. 浏览器自动打开了. 并且输入了网址. 也能拿到网页上的title标题.

![image-20210125175906255](https://s2.loli.net/2023/07/17/6ftbeoTCRyIZiF9.png)

cool~

## 2. selenium各种神奇操作

selenium不但可以打开浏览器. 还可以对浏览器各种操作. 比如, 点击, 查找. 都可以.

我们直接上案例. 抓取拉钩网招聘python工程师的招聘信息

### 2.1 准备工作

```python

from selenium.webdriver import Chrome

web = Chrome()

web.get("http://lagou.com")

```

![image-20210125180302833](https://s2.loli.net/2023/07/17/pAsV41fBcR5amQT.png)

###2.2 点击-全国按钮

想要点击这个按钮. 我们需要先定位到这个按钮. 然后再点击

selenium想要定位某个元素. 太简单了.

![image-20210125180558103](https://s2.loli.net/2023/07/17/dRSEcOGylUoirZM.png)

有了xpath是不是明白了些什么.

```python

from selenium.webdriver import Chrome

web = Chrome()

web.get("http://lagou.com")

btn = web.find_element_by_xpath('//*[@id="changeCityBox"]/ul/li[1]/a') # 找到全国按钮

btn.click() # 点击这个按钮

```

![image-20210125180745412](https://s2.loli.net/2023/07/17/vLrN39nozlT4tk1.png)

舒服!

### 2.3 搜索python

人的过程: 找到文本框输入"python", 点击"搜索"按钮.

机器的过程: 找到文本框输入"python", 点击"搜索"按钮.

发现没, 用selenium最爽的地方就是这里. 人是怎么操作的. 机器就怎么操作. 爽到极点

```python

# 找到文本框输入python, 点击搜索按钮

web.find_element_by_xpath('//*[@id="search_input"]').send_keys("python")

web.find_element_by_xpath('//*[@id="search_button"]').click()

```

send_keys() 这里要说一下. 如果我们给出的是一个字符串. 就是输入文本. 但是, 如果给出的是一个键盘指令, 那就按下键盘. 比如, 我想要按回车按钮. 就是这样的

```python

from selenium.webdriver import Chrome

from selenium.webdriver.common.keys import Keys

import time

web = Chrome()

web.get("http://lagou.com")

btn = web.find_element_by_xpath('//*[@id="changeCityBox"]/ul/li[1]/a') # 找到全国按钮

btn.click() # 点击这个按钮

time.sleep(2) # 让浏览器反应一会儿

# 找到文本框输入python, 点击搜索按钮

web.find_element_by_xpath('//*[@id="search_input"]').send_keys("python", Keys.ENTER)

# web.find_element_by_xpath('//*[@id="search_button"]').click()

```

![image-20210125181431480](https://s2.loli.net/2023/07/17/dtsq62J18XxCnrD.png)

keys里几乎包含了我们需要的所有特殊按键

### 2.4 提取招聘信息

```python

from selenium.webdriver import Chrome

from selenium.webdriver.common.keys import Keys

import time

web = Chrome()

web.get("http://lagou.com")

btn = web.find_element_by_xpath('//*[@id="changeCityBox"]/ul/li[1]/a') # 找到全国按钮

btn.click() # 点击这个按钮

time.sleep(2) # 让浏览器反应一会儿

# 找到文本框输入python, 点击搜索按钮

web.find_element_by_xpath('//*[@id="search_input"]').send_keys("python", Keys.ENTER)

time.sleep(1)

# web.find_element_by_xpath('//*[@id="search_button"]').click()

ls = web.find_elements_by_xpath('//*[@id="s_position_list"]/ul/li') # 一次性提取多个元素用elements

for item in ls:

name = item.find_element_by_xpath('./div[1]/div[1]/div[1]/a/h3').text

addr = item.find_element_by_xpath('./div[1]/div[2]/div[1]/a').text

print(name, addr)

# 其他内容你自己琢磨吧

```

发现没有, selenium几乎是傻瓜式的存在.

##3. 处理iframe, 多窗口调度

我们书接上回. 上回说到我们已经可以通过selenium拿到拉钩网的招聘信息了. 但是, 信息不够全面. 我们希望得到的不仅仅是一个岗位名称和公司名称, 我更想知道更加详细的职位描述以及岗位要求.

![image-20210126172555841](https://s2.loli.net/2023/07/17/CIJGsTBUjE34xtR.png)

此时问题就来了. 我们可以在搜索页面点击进入到这个详情页. 然后就可以看到想要的职位描述了. 但是, 这时就涉及到如何从一个窗口转向另一个窗口了(切换选项卡).

首先, 我们先通过selenium定位到搜索页上的职位超链接.

```python

from selenium.webdriver import Chrome

from selenium.webdriver.common.keys import Keys

import time

web = Chrome()

web.get("http://www.lagou.com")

web.find_element_by_xpath('//*[@id="changeCityBox"]/ul/li[1]/a').click()

time.sleep(2)

web.find_element_by_xpath('//*[@id="search_input"]').send_keys("python", Keys.ENTER)

time.sleep(2)

# 不要红包(拉钩的活动. 时有时无)

web.find_element_by_xpath('/html/body/div[8]/div/div[2]').click()

# 点击职位

web.find_element_by_xpath('//*[@id="s_position_list"]/ul/li[1]/div[1]/div[1]/div[1]/a/h3').click()

time.sleep(1)

```

正片开始

![image-20210126175042619](https://s2.loli.net/2023/07/17/QpMrj4AYLKwU2oi.png)

注意! 我们看到的是新窗口的内容, 但是在selenium的视角里, 窗口依然停留在刚才那个窗口. 此时, 必须要将窗口调整到最新的窗口上才可以.

```python

# 正片开始

web.switch_to.window(web.window_handles[-1]) # 跳转到最后一个窗口

job_detail = web.find_element_by_xpath('//*[@id="job_detail"]/dd[2]').text

print(job_detail)

```

接下来我们来看另一种操作.

之前我们抓取过一个网站. 里面把视频内容嵌套在一个iframe中. 那如果换成了selenium应该如何应对呢?

![image-20210709175412897](https://s2.loli.net/2023/07/17/d7K1n6hmCoIyicP.png)

```python

from selenium.webdriver import Chrome

web = Chrome()

web.get("http://www.wbdy.tv/play/42491_1_1.html")

# 找到那个iframe

iframe = web.find_element_by_xpath('//iframe[@id="mplay"]')

web.switch_to.frame(iframe)

val = web.find_element_by_xpath('//input[@class="dplayer-comment-input"]').get_attribute("placeholder")

print(val)

# 调整回上层结构

web.switch_to.parent_frame()

xxx = web.find_element_by_xpath('/html/body/div[2]/div[3]/div[2]/div/div[2]/h2').text

print(xxx)

```

## 4. 无头浏览器

我们已经基本了解了selenium的基本使用了. 但是呢, 不知各位有没有发现, 每次打开浏览器的时间都比较长. 这就比较耗时了. 我们写的是爬虫程序. 目的是数据. 并不是想看网页. 那能不能让浏览器在后台跑呢? 答案是可以的.

咱直接上案例吧. 拿出最开始我们看到的那个网页. 抓取电影票房. 并且用正常的有浏览器窗口的方式来抓取. 然后再改成后台运行不就好了么

```python

from selenium.webdriver import Chrome

from selenium.webdriver.support.select import Select

from selenium.webdriver.chrome.options import Options

import time

opt = Options()

opt.add_argument("--headless")

opt.add_argument('--disable-gpu')

web = Chrome(options=opt)

web.get('https://www.endata.com.cn/BoxOffice/BO/Year/index.html')

# 切换select

sel = Select(web.find_element_by_xpath('//*[@id="OptionDate"]'))

for i in range(len(sel.options)):

sel.select_by_index(i) # 按照索引位置切换

time.sleep(1)

table = web.find_element_by_xpath('//*[@id="TableList"]/table')

print("===========================================")

print(table.text)

```

## 5. 超级鹰搞定验证码

在进行爬虫抓取的时候遇到验证码怎么办? 这个问题其实一直都很蛋疼. 怎么解决呢?

1. 自己想办法写一套深度学习算法. 有针对的去学习各种验证码的识别方案

2. 使用互联网上已经相对成熟的产品进行验证码识别.

理性告诉我, 方案二更适合我.

这里推荐各位可以用超级鹰来做测试. 不同的平台使用的算法可能是不一样的. 但是调用方案几乎都差不太多.

我们来看看超级鹰怎么用. 首先, 登录超级鹰的官网. 然后需要注册. 注册后, 需要我们进入用户中心. 生成一个新的软件ID就可以用了

![image-20210202175436553](https://s2.loli.net/2023/07/17/LKdhu9DVwyxf6bn.png)

![image-20210202175456323](https://s2.loli.net/2023/07/17/ti4uSCqcbgvyZjk.png)

![image-20210202175513804](https://s2.loli.net/2023/07/17/guFP4c5xGvN3jXE.png)

注意这个号, 后面会用到.

然后我们回到超级鹰的官网. 找到测试代码. 找到python的测试代码, 下载. 丢到pycharm里

![image-20210202175619221](https://s2.loli.net/2023/07/17/9NpadXPhI3BLO82.png)

![image-20210202175637499](https://s2.loli.net/2023/07/17/U2jpg5z4hIB7XWR.png)

下载好的内容解压. 丢到pycharm中.

![image-20210202175728621](https://s2.loli.net/2023/07/17/PJrslk93EFQzfBx.png)

![image-20210202175920448](https://s2.loli.net/2023/07/17/Zsd8BVPjHvKEckt.png)

最后, 测试一下

![image-20210202175947934](https://s2.loli.net/2023/07/17/fMFTIhPCZSNy8cd.png)

识别效果还是不错的.

```python

#!/usr/bin/env python

# coding:utf-8

import requests

from hashlib import md5

class Chaojiying_Client(object):

def init(self, username, password, soft_id):

self.username = username

password = password.encode('utf8')

self.password = md5(password).hexdigest()

self.soft_id = soft_id

self.base_params = {

'user': self.username,

'pass2': self.password,

'softid': self.soft_id,

}

self.headers = {

'Connection': 'Keep-Alive',

'User-Agent': 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)',

}

def PostPic(self, im, codetype):

"""

im: 图片字节

codetype: 题目类型 参考 http://www.chaojiying.com/price.html

"""

params = {

'codetype': codetype,

}

params.update(self.base_params)

files = {'userfile': ('ccc.jpg', im)}

r = requests.post('http://upload.chaojiying.net/Upload/Processing.php', data=params, files=files, headers=self.headers)

return r.json()

def ReportError(self, im_id):

"""

im_id:报错题目的图片ID

"""

params = {

'id': im_id,

}

params.update(self.base_params)

r = requests.post('http://upload.chaojiying.net/Upload/ReportError.php', data=params, headers=self.headers)

return r.json()

if name == '__main__':

chaojiying = Chaojiying_Client('18614075987', '6035945', '912488')

im = open('a.jpg', 'rb').read()

print(chaojiying.PostPic(im, 1902))

```

如果遇到的验证码比较特殊. 可以更换代码中的1902位置的参数值. 具体情况可以参考官网上给出的参数列表

![image-20210202180109096](https://s2.loli.net/2023/07/17/itz2xaZjgwul5SB.png)

需要哪个填哪个就行.

各位可以自行做个测试. 用超级鹰来破解超级鹰的登录验证码~~ 相信会很有意思.

## 6. 超级鹰干超级鹰

本小节, 我们用超级鹰来破解超级鹰的验证码. 看看效果如何~

```python

from selenium.webdriver import Chrome

from chaojiying import Chaojiying_Client

import time

web = Chrome()

web.get("http://www.chaojiying.com/user/login/")

code_img = web.find_element_by_xpath('/html/body/div[3]/div/div[3]/div[1]/form/div/img')

png_code_img = code_img.screenshot_as_png # 拿到img的截图

chaojiying = Chaojiying_Client('18614075987', '6035945', '912488')

result = chaojiying.PostPic(png_code_img, 1902)

web.find_element_by_xpath('/html/body/div[3]/div/div[3]/div[1]/form/p[1]/input').send_keys('18614075987')

web.find_element_by_xpath('/html/body/div[3]/div/div[3]/div[1]/form/p[2]/input').send_keys('6035945')

web.find_element_by_xpath('/html/body/div[3]/div/div[3]/div[1]/form/p[3]/input').send_keys(result['pic_str'])

time.sleep(10)

web.find_element_by_xpath('/html/body/div[3]/div/div[3]/div[1]/form/p[4]/input').click()

```

## 7. 图鉴-好东西

![image-20210720170234915](https://s2.loli.net/2023/07/17/aio3Lh41VBGj5Mq.png)

这个东西. 既便宜. 有好用. 比超级鹰爽.

注册个账号. 如果不想注册. 直接用我的也OK

然后就可以用了.

官方示例:

```python

import base64

import json

import requests

# 一、图片文字类型(默认 3 数英混合):

# 1 : 纯数字

# 1001:纯数字2

# 2 : 纯英文

# 1002:纯英文2

# 3 : 数英混合

# 1003:数英混合2

# 4 : 闪动GIF

# 7 : 无感学习(独家)

# 11 : 计算题

# 1005: 快速计算题

# 16 : 汉字

# 32 : 通用文字识别(证件、单据)

# 66: 问答题

# 49 :recaptcha图片识别 参考 https://shimo.im/docs/RPGcTpxdVgkkdQdY

# 二、图片旋转角度类型:

# 29 : 旋转类型

#

# 三、图片坐标点选类型:

# 19 : 1个坐标

# 20 : 3个坐标

# 21 : 3 ~ 5个坐标

# 22 : 5 ~ 8个坐标

# 27 : 1 ~ 4个坐标

# 48 : 轨迹类型

#

# 四、缺口识别

# 18 : 缺口识别(需要2张图 一张目标图一张缺口图)

# 33 : 单缺口识别(返回X轴坐标 只需要1张图)

# 五、拼图识别

# 53:拼图识别

def base64_api(uname, pwd, img, typeid):

with open(img, 'rb') as f:

base64_data = base64.b64encode(f.read())

b64 = base64_data.decode()

data = {"username": uname, "password": pwd, "typeid": typeid, "image": b64}

result = json.loads(requests.post("http://api.ttshitu.com/predict", json=data).text)

if result['success']:

return result["data"]["result"]

else:

return result["message"]

return ""

if name == "__main__":

img_path = "换成你自己的图片.jpg"

result = base64_api(uname='q6035945', pwd='q6035945', img=img_path, typeid=3)

print(result)

```

非常的简单. 可以自行先爽一下. 下节课我们来使用图鉴, 完成验证码的处理.

0

评论区