【第五章-1】Python爬虫教程(selenium、爬取拉勾网招聘信息、多窗口调度、iframe处理、无头浏览器【不弹出浏览器窗口】、获得页面代码Elements)

本课程共五个章节,课程地址:

【Python爬虫教程】花9888买的Python爬虫全套教程2021完整版现分享给大家!(已更新项目)——附赠课程与资料_哔哩哔哩_bilibili


第五章

  1. selenium概述
  2. selenium各种神奇操作
  3. 多窗口调度及iframe处理 
  4. 无头浏览器
  5. 超级鹰基本使用
  6. 超级鹰干超级鹰
  7. 模拟12306登录 

目录

第五章

(一)selenium概述

环境搭建

使用 

(二)selenium各种神奇操作

第一步:打开拉勾网

第二步:点击 “北京” 按钮

第三步:在搜索框里输入“python”,按下回车或点击“搜索”按钮 

第四步:查找存放数据的位置,进行数据提取 

完整代码

(三)多窗口调度及iframe处理 

窗口之间的切换

页面中遇到了 iframe 如何处理 

(四)无头浏览器 

正常的有浏览器窗口的方式来抓取

让 selenium 在后台执行

如何拿到页面代码 Elements(经过数据加载及js执行后的结果的html内容,不是页面源代码)


(一)selenium概述

想抓取电影票房:艺恩娱数 

右键 ——> 查看网页源代码,发现数据不在页面源代码中 

故而 f12 ——> Network

内容正常(网页貌似又改版了emmm,那就用课程PPT上的截图) 

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

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

数据找到了,点击 Preview 预览:

我们发现这个数据是经过加密算法的,直接通过 requests 拿到这些内容必须要解密才能看到真实数据,但是该网站采用的加密方式又不是那么容易破解。此时,如果我能通过我的程序直接调用浏览器,让浏览器去解密这些内容,我们直接拿结果就好了。这就引出了本章的 selenium 

  • 需求:能不能让我的程序连接到浏览器,让浏览器来完成各种复杂的操作,我们只接收最终的结果
  • selenium:本身是一个自动化测试工具,可以启动一个全新的浏览器,并从浏览器中提取到你想要的内容
  • 程序员可以从 selenium 中直接提取网页上的各种信息。随着各种网站的反爬机制的出现,selenium 越来越受到程序员的喜爱
  • 适用场景:爬取加密之后的东西;爬取动态加载数据的网页
  • 缺点:要启动一个第三方的软件(浏览器),并且还要等待浏览器把数据渲染完毕,这个过程必然是很耗时的,所以它慢

环境搭建

安装: 

pip install selenium --trusted-host pypi.tuna.tsinghua.edu.cn

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

下载浏览器驱动: 

chrome浏览器驱动地址: 

CNPM Binaries Mirror

查询自己chrome浏览器的版本: 

如果版本号对不上,可以对应前三位即可,即104.0.5112,最后一位找最接近的: 

win64 选 win32 即可 

下载并解压,把解压缩的浏览器驱动 chromedriver 放在 python解释器 所在的文件夹

 python解释器所在的文件夹怎么找?   随便运行一个 .py 文件

使用 

测试一下,让 selenium 启动谷歌浏览器:

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

# 1.创建浏览器对象
web = Chrome()
# 2.打开一个网址
web.get("http://www.baidu.com")

print(web.title)

运行一下会发现浏览器自动打开了,并且输入了网址,也能拿到网页上的 title标题(百度一下,你就知道) 


(二)selenium各种神奇操作

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

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

第一步:打开拉勾网

from selenium.webdriver import Chrome

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

第二步:点击 “北京” 按钮

想要点击这个按钮,我们需要先定位到这个按钮,然后再点击 selenium 想要定位的某个元素 

from selenium.webdriver.common import by

# 找到某个元素,点击它
# web.find_elements() 找全部;web.find_element() 找一个
el = web.find_element(by.By.XPATH, '//*[@id="changeCityBox"]/ul/li[1]/a')   # 北京的按钮
el.click()   # 点击事件

第三步:在搜索框里输入“python”,按下回车或点击“搜索”按钮 

from selenium.webdriver.common import by
from selenium.webdriver.common.keys import Keys   # 模拟键盘上的键
import time

time.sleep(1)   # 让浏览器缓一会,等页面加载完(ajax)

# 找到输入框,输入python ——> 输入回车(以这种为例)/点击搜索按钮(和上面的思路一样,不再赘述)
web.find_element(by.By.XPATH, '//*[@id="search_input"]').send_keys("python", Keys.ENTER)    # 回车

send_keys() :

如果我们给出的是一个字符串,就是输入文本;

如果给出的是一个键盘指令,那就按下键盘,比如,我想要按回车按钮,就是这样的:

from selenium.webdriver.common.keys import Keys
web.find_element(by.By.XPATH,  ' ' ).send_keys( Keys.ENTER)
Keys里几乎包含了我们需要的所有特殊按键

第四步:查找存放数据的位置,进行数据提取 

复制岗位名称的XPath 

复制薪资的XPath

其他以此类推 

time.sleep(1)

# 查找存放数据的位置,进行数据提取
li_list = web.find_elements(by.By.XPATH, '//*[@id="jobList"]/div[1]/div')   # 找到页面中存放数据的所有url
for li in li_list:
    job_name = li.find_element(by.By.XPATH, './div[1]/div[1]/div[1]/a').text   # 职位名称
    job_price = li.find_element(by.By.XPATH, './div[1]/div[1]/div[2]/span').text    # 薪资
    company_name = li.find_element(by.By.XPATH, './div[1]/div[2]/div[1]/a').text   # 公司名称
    print(company_name, job_name, job_price)

完整代码: 

from selenium.webdriver import Chrome
from selenium.webdriver.common import by
from selenium.webdriver.common.keys import Keys   # 模拟键盘上的键
import time

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

# 找到某个元素,点击它
# web.find_elements() 找全部;web.find_element() 找一个
el = web.find_element(by.By.XPATH, '//*[@id="changeCityBox"]/ul/li[1]/a')   # 北京的按钮
el.click()   # 点击事件

time.sleep(1)   # 让浏览器缓一会,等页面加载完(ajax)

# 找到输入框,输入python ——> 输入回车(以这种为例)/点击搜索按钮(和上面的思路一样,不再赘述)
web.find_element(by.By.XPATH, '//*[@id="search_input"]').send_keys("python", Keys.ENTER)    # 回车

time.sleep(1)

# 查找存放数据的位置,进行数据提取
li_list = web.find_elements(by.By.XPATH, '//*[@id="jobList"]/div[1]/div')   # 找到页面中存放数据的所有url
for li in li_list:
    job_name = li.find_element(by.By.XPATH, './div[1]/div[1]/div[1]/a').text   # 职位名称
    job_price = li.find_element(by.By.XPATH, './div[1]/div[1]/div[2]/span').text    # 薪资
    company_name = li.find_element(by.By.XPATH, './div[1]/div[2]/div[1]/a').text   # 公司名称
    print(company_name, job_name, job_price)

(三)多窗口调度及iframe处理 

窗口之间的切换: 

上节我们已经可以通过 selenium 拿到拉勾网的招聘信息了,但是信息不够全面,我们希望得到的不仅仅是一个岗位名称和公司名称,而是更加详细的职位描述和岗位要求 

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

想要爬取上图中的 “职位描述”

  1. 首先,先通过 selenium 定位到搜索页上的职位超链接
  2. 我们看到的是新窗口的内容,但是在 selenium 的视角里,窗口依然停留在刚才那个窗口,此时必须要将窗口调整到最新的窗口上才可以
from selenium.webdriver import Chrome
from selenium.webdriver.common import by
from selenium.webdriver.common.keys import Keys
import time

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

web.find_element(by.By.XPATH , '//*[@id="cboxClose"]').click()   # 点x
time.sleep(1)

web.find_element(by.By.XPATH, '//*[@id="search_input"]').send_keys("python", Keys.ENTER)
time.sleep(1)

web.find_element(by.By.XPATH, '//*[@id="jobList"]/div[1]/div[1]/div[1]/div[1]/div[1]/a').click()

# 如何进入到新窗口中进行提取
# 注意,在selenium的眼中,新窗口默认是不切换过来的
web.switch_to.window(web.window_handles[-1])   # 切换到选项栏里的最后一个窗口
# 在新窗口中提取内容
job_detail = web.find_element(by.By.XPATH, '//*[@id="job_detail"]/dd[2]/div').text    # 职位描述
print(job_detail)

爬取完毕后,再回到原来的页面: 

# 关掉子窗口
web.close()
# 变更selenium的视角,将视角切换到原来的窗口
web.switch_to.window(web.window_handles[0])
print(web.find_element(by.By.XPATH, '//*[@id="jobList"]/div[1]/div[1]/div[1]/div[1]/div[1]/a').text)

 

页面中遇到了 iframe 如何处理 

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

梦华录详情介绍-梦华录在线观看-梦华录迅雷下载 - 看剧柒柒-77影视-77电影-看剧77-77影视-影视大全免费追剧-柒柒看剧

  

# 如果页面中遇到了 iframe 如何处理
web.get("https://kanju77.com/vy/107438-1-1/")
# 处理iframe的话,必须先拿到iframe,然后切换视角到iframe,才可以拿数据
iframe = web.find_element(by.By.XPATH, '//*[@id="playleft"]/iframe')
web.switch_to.frame(iframe)   # 切换到iframe
tx = web.find_element(by.By.XPATH, '//*[@id="mse"]/video').get_attribute("src")
print(tx)

# 再从iframe里切换回原页面
# web.switch_to.default_content()

播放器中的视频地址是一个 blob:https,它并不是一种协议,而是 html5 中 blob对象在赋给video标签后生成的一串标记,简单来说,就是防止爬虫能直接拿到视频下载地址,中间倒了一手 


(四)无头浏览器 

前三节我们已经了解了 selenium 的基本使用,但是每次打开浏览器的时间都比较长,这就很耗时。我们写的是爬虫程序,目的是数据,并不是想看网页,那能不能让浏览器在后台跑呢?这就涉及到无头浏览器的内容 

课程上案例的网址已经失效了,但还是以其代码为例来抓取电影票房,说明 selenium 对下拉列表的处理

下拉列表:select 标签

另一种:通过css动态渲染出下拉效果

例如:

<select>

        <option value=1>哈哈</option>

</select> 

value就是1,visible_text就是哈哈

正常的有浏览器窗口的方式来抓取:

from selenium.webdriver import Chrome
from selenium.webdriver.common import by
from selenium.webdriver.support.select import Select
import time

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

# 定位到下拉列表(电影票房选取年份  select)
sel_el = web.find_element(by.By.XPATH, '//*[@id="OptionDate"]')   # 元素类型
# 对元素进行包装, 包装成下拉菜单
sel = Select(sel_el)   # select类型
# 让浏览器进行调整选项(切换年份  option)
for i in range(len(sel.options)):  # i就是每一个下拉框选项的索引位置
    # .select_by_index  根据索引进行选择
    # .select_by_value  根据value进行选择
    # .select_by_visible_text  根据你所见的文本进行选择
    sel.select_by_index(i)    # 按照索引进行切换
    time.sleep(2)    # 每次切换都发送一次网络请求,所以要等它加载完
    table = web.find_element(by.By.XPATH, '//*[@id="TableList"]/table')
    print(table.text)  # 打印所有文本信息
    print("===================================")

print("运行完毕.  ")
web.close()

让 selenium 在后台执行: 

主要添加的部分:

from selenium.webdriver.chrome.options import Options   # 配置

# 准备好参数配置
opt = Options()
opt.add_argument("--headless")
opt.add_argument("--disable-gpu")

web = Chrome(options=opt)  # 把参数配置设置到浏览器中

完整代码:

from selenium.webdriver import Chrome
from selenium.webdriver.chrome.options import Options   # 配置
from selenium.webdriver.common import by
from selenium.webdriver.support.select import Select
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_el = web.find_element(by.By.XPATH, '//*[@id="OptionDate"]')   # 元素类型
# 对元素进行包装, 包装成下拉菜单
sel = Select(sel_el)   # select类型
# 让浏览器进行调整选项(切换年份  option)
for i in range(len(sel.options)):  # i就是每一个下拉框选项的索引位置
    # .select_by_index  根据索引进行选择
    # .select_by_value  根据value进行选择
    # .select_by_visible_text  根据你所见的文本进行选择
    sel.select_by_index(i)    # 按照索引进行切换
    time.sleep(2)    # 每次切换都发送一次网络请求,所以要等它加载完
    table = web.find_element(by.By.XPATH, '//*[@id="TableList"]/table')
    print(table.text)  # 打印所有文本信息
    print("===================================")

print("运行完毕.  ")
web.close()

如何拿到页面代码 Elements(经过数据加载及js执行后的结果的html内容,不是页面源代码

标准的 ajax 请求把数据加载到页面当中,不是在页面源代码里体现。所以右键 ——> 查看网页源代码f12 ——> Elements(看到的是js ajax加载完了,实时的用户所见即所得的内容) 看到的内容可能不一样

# 准备好参数配置
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")

time.sleep(2)   # 等待js加载完数据

# 如何拿到页面代码Elements(经过数据加载以及js执行之后的结果的html内容)
print(web.page_source)
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Cheer-ego

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值