当前位置:   article > 正文

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

【第五章-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 启动谷歌浏览器:

  1. from selenium.webdriver import Chrome # 导入谷歌浏览器的类
  2. # 1.创建浏览器对象
  3. web = Chrome()
  4. # 2.打开一个网址
  5. web.get("http://www.baidu.com")
  6. print(web.title)

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


(二)selenium各种神奇操作

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

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

第一步:打开拉勾网

  1. from selenium.webdriver import Chrome
  2. web = Chrome()
  3. web.get("http://lagou.com")

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

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

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

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

  1. from selenium.webdriver.common import by
  2. from selenium.webdriver.common.keys import Keys # 模拟键盘上的键
  3. import time
  4. time.sleep(1) # 让浏览器缓一会,等页面加载完(ajax)
  5. # 找到输入框,输入python ——> 输入回车(以这种为例)/点击搜索按钮(和上面的思路一样,不再赘述)
  6. 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

其他以此类推 

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

完整代码: 

  1. from selenium.webdriver import Chrome
  2. from selenium.webdriver.common import by
  3. from selenium.webdriver.common.keys import Keys # 模拟键盘上的键
  4. import time
  5. web = Chrome()
  6. web.get("http://lagou.com")
  7. # 找到某个元素,点击它
  8. # web.find_elements() 找全部;web.find_element() 找一个
  9. el = web.find_element(by.By.XPATH, '//*[@id="changeCityBox"]/ul/li[1]/a') # 北京的按钮
  10. el.click() # 点击事件
  11. time.sleep(1) # 让浏览器缓一会,等页面加载完(ajax)
  12. # 找到输入框,输入python ——> 输入回车(以这种为例)/点击搜索按钮(和上面的思路一样,不再赘述)
  13. web.find_element(by.By.XPATH, '//*[@id="search_input"]').send_keys("python", Keys.ENTER) # 回车
  14. time.sleep(1)
  15. # 查找存放数据的位置,进行数据提取
  16. li_list = web.find_elements(by.By.XPATH, '//*[@id="jobList"]/div[1]/div') # 找到页面中存放数据的所有url
  17. for li in li_list:
  18. job_name = li.find_element(by.By.XPATH, './div[1]/div[1]/div[1]/a').text # 职位名称
  19. job_price = li.find_element(by.By.XPATH, './div[1]/div[1]/div[2]/span').text # 薪资
  20. company_name = li.find_element(by.By.XPATH, './div[1]/div[2]/div[1]/a').text # 公司名称
  21. print(company_name, job_name, job_price)

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

窗口之间的切换: 

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

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

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

  1. 首先,先通过 selenium 定位到搜索页上的职位超链接
  2. 我们看到的是新窗口的内容,但是在 selenium 的视角里,窗口依然停留在刚才那个窗口,此时必须要将窗口调整到最新的窗口上才可以
  1. from selenium.webdriver import Chrome
  2. from selenium.webdriver.common import by
  3. from selenium.webdriver.common.keys import Keys
  4. import time
  5. web = Chrome()
  6. web.get("http://lagou.com")
  7. web.find_element(by.By.XPATH , '//*[@id="cboxClose"]').click() # 点x
  8. time.sleep(1)
  9. web.find_element(by.By.XPATH, '//*[@id="search_input"]').send_keys("python", Keys.ENTER)
  10. time.sleep(1)
  11. web.find_element(by.By.XPATH, '//*[@id="jobList"]/div[1]/div[1]/div[1]/div[1]/div[1]/a').click()
  12. # 如何进入到新窗口中进行提取
  13. # 注意,在selenium的眼中,新窗口默认是不切换过来的
  14. web.switch_to.window(web.window_handles[-1]) # 切换到选项栏里的最后一个窗口
  15. # 在新窗口中提取内容
  16. job_detail = web.find_element(by.By.XPATH, '//*[@id="job_detail"]/dd[2]/div').text # 职位描述
  17. print(job_detail)

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

  1. # 关掉子窗口
  2. web.close()
  3. # 变更selenium的视角,将视角切换到原来的窗口
  4. web.switch_to.window(web.window_handles[0])
  5. 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影视-影视大全免费追剧-柒柒看剧

  

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

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


(四)无头浏览器 

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

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

下拉列表:select 标签

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

例如:

<select>

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

</select> 

value就是1,visible_text就是哈哈

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

  1. from selenium.webdriver import Chrome
  2. from selenium.webdriver.common import by
  3. from selenium.webdriver.support.select import Select
  4. import time
  5. web = Chrome()
  6. web.get("https://www.endata.com.cn/BoxOffice/BO/Year/index.html")
  7. # 定位到下拉列表(电影票房选取年份 select)
  8. sel_el = web.find_element(by.By.XPATH, '//*[@id="OptionDate"]') # 元素类型
  9. # 对元素进行包装, 包装成下拉菜单
  10. sel = Select(sel_el) # select类型
  11. # 让浏览器进行调整选项(切换年份 option)
  12. for i in range(len(sel.options)): # i就是每一个下拉框选项的索引位置
  13. # .select_by_index 根据索引进行选择
  14. # .select_by_value 根据value进行选择
  15. # .select_by_visible_text 根据你所见的文本进行选择
  16. sel.select_by_index(i) # 按照索引进行切换
  17. time.sleep(2) # 每次切换都发送一次网络请求,所以要等它加载完
  18. table = web.find_element(by.By.XPATH, '//*[@id="TableList"]/table')
  19. print(table.text) # 打印所有文本信息
  20. print("===================================")
  21. print("运行完毕. ")
  22. web.close()

让 selenium 在后台执行: 

主要添加的部分:

  1. from selenium.webdriver.chrome.options import Options # 配置
  2. # 准备好参数配置
  3. opt = Options()
  4. opt.add_argument("--headless")
  5. opt.add_argument("--disable-gpu")
  6. web = Chrome(options=opt) # 把参数配置设置到浏览器中

完整代码:

  1. from selenium.webdriver import Chrome
  2. from selenium.webdriver.chrome.options import Options # 配置
  3. from selenium.webdriver.common import by
  4. from selenium.webdriver.support.select import Select
  5. import time
  6. # 准备好参数配置
  7. opt = Options()
  8. opt.add_argument("--headless")
  9. opt.add_argument("--disable-gpu")
  10. web = Chrome(options=opt) # 把参数配置设置到浏览器中
  11. web.get("https://www.endata.com.cn/BoxOffice/BO/Year/index.html")
  12. # 定位到下拉列表(电影票房选取年份 select)
  13. sel_el = web.find_element(by.By.XPATH, '//*[@id="OptionDate"]') # 元素类型
  14. # 对元素进行包装, 包装成下拉菜单
  15. sel = Select(sel_el) # select类型
  16. # 让浏览器进行调整选项(切换年份 option)
  17. for i in range(len(sel.options)): # i就是每一个下拉框选项的索引位置
  18. # .select_by_index 根据索引进行选择
  19. # .select_by_value 根据value进行选择
  20. # .select_by_visible_text 根据你所见的文本进行选择
  21. sel.select_by_index(i) # 按照索引进行切换
  22. time.sleep(2) # 每次切换都发送一次网络请求,所以要等它加载完
  23. table = web.find_element(by.By.XPATH, '//*[@id="TableList"]/table')
  24. print(table.text) # 打印所有文本信息
  25. print("===================================")
  26. print("运行完毕. ")
  27. web.close()

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

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

  1. # 准备好参数配置
  2. opt = Options()
  3. opt.add_argument("--headless")
  4. opt.add_argument("--disable-gpu")
  5. web = Chrome(options=opt) # 把参数配置设置到浏览器中
  6. web.get("https://www.endata.com.cn/BoxOffice/BO/Year/index.html")
  7. time.sleep(2) # 等待js加载完数据
  8. # 如何拿到页面代码Elements(经过数据加载以及js执行之后的结果的html内容)
  9. print(web.page_source)
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/木道寻08/article/detail/939812
推荐阅读
相关标签
  

闽ICP备14008679号