赞
踩
本课程共五个章节,课程地址:
【Python爬虫教程】花9888买的Python爬虫全套教程2021完整版现分享给大家!(已更新项目)——附赠课程与资料_哔哩哔哩_bilibili
目录
第三步:在搜索框里输入“python”,按下回车或点击“搜索”按钮
如何拿到页面代码 Elements(经过数据加载及js执行后的结果的html内容,不是页面源代码)
想抓取电影票房:艺恩娱数
右键 ——> 查看网页源代码,发现数据不在页面源代码中
故而 f12 ——> Network
内容正常(网页貌似又改版了emmm,那就用课程PPT上的截图)
我们在抓取一些普通网页的时候 requests 基本上是可以满足的,但是如果遇到一些特殊的网站,它的数据是经过加密的,而浏览器却能够正常显示出来,那我们通过 requests 抓取到的内容可能就不是我们想要的结果了。例如:
电影票房数据,在浏览器上看的时候是正常的,那么按照之前的逻辑,我们只需要看看数据是通过哪个请求拿到的就可以进行模拟请求了
数据找到了,点击 Preview 预览:
我们发现这个数据是经过加密算法的,直接通过 requests 拿到这些内容必须要解密才能看到真实数据,但是该网站采用的加密方式又不是那么容易破解。此时,如果我能通过我的程序直接调用浏览器,让浏览器去解密这些内容,我们直接拿结果就好了。这就引出了本章的 selenium
安装:
pip install selenium --trusted-host pypi.tuna.tsinghua.edu.cn
selenium 与其他库不同的地方在于:它要启动你电脑上的浏览器,这就需要一个驱动程序来辅助
下载浏览器驱动:
chrome浏览器驱动地址:
查询自己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 不但可以打开浏览器,还可以对浏览器各种操作,如点击、查找都可以
我们直接上案例:抓取拉勾网招聘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() # 点击事件
- 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 Keysweb.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)
上节我们已经可以通过 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 中。那么换成了 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()
主要添加的部分:
- 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()
标准的 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)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。