在使用python做爬虫的过程中,有些页面的的部分数据是通过js异步加载的,js调用接口的请求中有时还带有些加密的参数很难破解无法使用requests这样的包直接爬取数据,因此需要借助seleniu来完成js的自动加载。
通过selenium 模拟浏览器的真是操作来获取页面中的所有请求,并且可以查找到一下页面上一些隐藏的元素,这些元素在html源码中无法看到,并且和能通过xpath和正则来捕获,因此需要使用selenium来查找隐藏元素,例如视频网站的播放按钮
代码如下
import time # 导入自动化测试模块 from selenium import webdriver from selenium.webdriver.common.desired_capabilities import DesiredCapabilities from selenium.webdriver.common.action_chains import ActionChains import re import json d = DesiredCapabilities.CHROME d['loggingPrefs'] = {'performance': 'ALL'} # 设置谷歌浏览器参数,设置语言和浏览器版本(使用真实浏览器头信息代替字符浏览器头) options = webdriver.ChromeOptions() options.add_argument('lang=zh_CN.UTF-8') options.add_argument('user-agent="Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Mobile Safari/537.36"') # 建立一个浏览器对象,调用PhantoJS来生成一个对象 browser = webdriver.Chrome(executable_path='D:\Python36\chromedriver.exe', chrome_options=options, desired_capabilities=d) video_url = 'https://v.youku.com/v_show/id_XNDIyMjU1NjgzMg==.html".ykplayer") # 查找页面隐藏元素 # menu = browser.find_element_by_css_selector("div.x-video-play-ico.i-pause > dt").text print(menu) print(type(menu)) menu = browser.find_element_by_css_selector(".ykplayer").text # 获得隐藏元素的内容 print(menu) print(type(menu)) ################### #ActionChains(browser).click() browser.find_element_by_css_selector('.ykplayer').click() # 查找到隐藏元素位置后执行点击鼠标左键操作 time.sleep(10) lo = browser.get_log('performance') # 捕获浏览器network中的数据 browser.get_network_conditions() datalist = [] for entry in lo: try: print(entry) datalist.append(entry) except Exception as e: continue browser.close()
视频中被播放按钮是一个隐藏元素,用xpaht定位到指定的标签后也无法获取这个标签中的元素
通过 browser.find_element_by_css_selector(“.ykplayer”)
方法查找 .ykplayer 可以查找到,查找后输出的内容这个视频的标题,这样就实现了使用chromedriver
自动播放视频的功能
这里虽然实现的视频自动播放,但是请求优酷视频的视频地址的接口调用的结果却依然没法通过 browser.get_log(‘performance')
来获得,原因是有一部分数据没有全部加载,但接口实际已经取得了完整的数据。虽然可以通过 get_log中的结果获得请求的地址,但是这个请求的地址在此使用requests进行请求会提示无权访问,可以看到这个请求已经有请求体了,但是使用get_log却无法捕获。
而且这个请求地址是一次性的,在次请求的结果是没权限
{"cost":0.003000000026077032,"data":{"error":{"note":"客户端无权播放,201","code":-6004}},"e":{"code":0,"provider":"hsfprovider","desc":""}}
要解决这个问题需要使用到browsermob-proxy
利用BrowserMob Proxy实现类似chrome的开发者工具中network的功能,
监控浏览器中该页面的request,获取对应的response,从而得到对应的json数据。
其大致原理是设置一个本地代理,并监控浏览器通过该代理的网络活动。
最后,我的解决方案是:python3 + selenium + chrome + browsermob-proxy
下载好BrowserMob Proxy和chromedriver,并记住对应的路径,稍后需要配置。
https://bmp.lightbody.net/
http://npm.taobao.org/mirrors/chromedriver/
另外,使用browsermob-proxy
需要安装Java依赖环境,首次安装后可能需要重启。
python的环境可安装anaconda获得,然后是安装额外的python库
pip install browsermob-proxy pip install selenium
软件环境配置完成后,可开始搭建抓取动态网页的框架,
下面是我做的一个简单框架(browsermonitor.py),其中未涉及数据的加工,可针对需要抓取的网页,直接继承后,根据需求加工数据:
"""step 1 导入依赖库""" from os import path from browsermobproxy import Server from selenium import webdriver import re """step 2 新建浏览器监控类""" class Monitor(object): """ step 3 配置chromedriver 和 browermobproxy 路径 需要使用完整路径,否则browsermobproxy无法启动服务 我是将这两个部分放到了和monitor.py同一目录 同时设置chrome为屏蔽图片,若需要抓取图片可自行修改 """ PROXY_PATH = path.abspath("./browsermob-proxy/bin/browsermob-proxy.bat") CHROME_PATH = path.abspath("./chromedriver.exe") CHROME_OPTIONS = {"profile.managed_default_content_settings.images":2} def __init__(self): """ 类初始化函数暂不做操作 """ pass def initProxy(self): """ step 4 初始化 browermobproxy 设置需要屏蔽的网络连接,此处屏蔽了css,和图片(有时chrome的设置会失效),可加快网页加载速度 新建proxy代理地址 """ self.server = Server(self.PROXY_PATH) self.server.start() self.proxy = self.server.create_proxy() self.proxy.blacklist(["http://.*/.*.css.*","http://.*/.*.jpg.*","http://.*/.*.png.*","http://.*/.*.gif.*"],200) def initChrome(self): """ step 5 初始化selenium, chrome设置 将chrome的代理设置为browermobproxy新建的代理地址 """ chromeSettings = webdriver.ChromeOptions() chromeSettings.add_argument('--proxy-server={host}:{port}'.format(host = "localhost", port = self.proxy.port)) chromeSettings.add_experimental_option("prefs", self.CHROME_OPTIONS) self.driver = webdriver.Chrome(executable_path = self.CHROME_PATH, chrome_options = chromeSettings) def genNewRecord(self, name = "monitor", options={'captureContent':True}): """ step 6 新建监控记录,设置内容监控为True """ self.proxy.new_har(name,options = options) def getContentText(self, targetUrl): """ step 7 简单的获取目标数据的函数 其中 targetUrl 为浏览器获取对应数据调用的url,需要用正则表达式表示 """ if self.proxy.har['log']['entries']: for loop_record in self.proxy.har['log']['entries']: try: if re.fullmatch(targetUrl , loop_record["request"]['url']): return loop_record["response"]['content']["text"] except Exception as err: print(err) continue return None def Start(self): """step 8 配置monitor的启动顺序""" try: self.initProxy() self.initChrome() except Exception as err: print(err) def Quit(self): """ step 9 配置monitor的退出顺序 代理sever的退出可能失败,目前是手动关闭,若谁能提供解决方法,将不胜感激 """ self.driver.close() self.driver.quit() try: self.proxy.close() self.server.process.terminate() self.server.process.wait() self.server.process.kill() except OSError: pass if __name__ == '__main__': monitor = Monitor() monitor.Start() monitor.genNewRecord() # 这使用优酷视频的地址 url = 'https://v.youku.com/v_show/id_XNDIyMjU1NjgzMg==.html"https://ups.youku.com/ups/get.json.*" # 这是获取视频播放地址的接口请求的前缀 text = monitor.getContentText(targetUrl) monitor.Quit()
总结
以上所述是小编给大家介绍的python selenium 查找隐藏元素 自动播放视频功能,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!
稳了!魔兽国服回归的3条重磅消息!官宣时间再确认!
昨天有一位朋友在大神群里分享,自己亚服账号被封号之后居然弹出了国服的封号信息对话框。
这里面让他访问的是一个国服的战网网址,com.cn和后面的zh都非常明白地表明这就是国服战网。
而他在复制这个网址并且进行登录之后,确实是网易的网址,也就是我们熟悉的停服之后国服发布的暴雪游戏产品运营到期开放退款的说明。这是一件比较奇怪的事情,因为以前都没有出现这样的情况,现在突然提示跳转到国服战网的网址,是不是说明了简体中文客户端已经开始进行更新了呢?
更新动态
- 凤飞飞《我们的主题曲》飞跃制作[正版原抓WAV+CUE]
- 刘嘉亮《亮情歌2》[WAV+CUE][1G]
- 红馆40·谭咏麟《歌者恋歌浓情30年演唱会》3CD[低速原抓WAV+CUE][1.8G]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[320K/MP3][193.25MB]
- 【轻音乐】曼托凡尼乐团《精选辑》2CD.1998[FLAC+CUE整轨]
- 邝美云《心中有爱》1989年香港DMIJP版1MTO东芝首版[WAV+CUE]
- 群星《情叹-发烧女声DSD》天籁女声发烧碟[WAV+CUE]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[FLAC/分轨][748.03MB]
- 理想混蛋《Origin Sessions》[320K/MP3][37.47MB]
- 公馆青少年《我其实一点都不酷》[320K/MP3][78.78MB]
- 群星《情叹-发烧男声DSD》最值得珍藏的完美男声[WAV+CUE]
- 群星《国韵飘香·贵妃醉酒HQCD黑胶王》2CD[WAV]
- 卫兰《DAUGHTER》【低速原抓WAV+CUE】
- 公馆青少年《我其实一点都不酷》[FLAC/分轨][398.22MB]
- ZWEI《迟暮的花 (Explicit)》[320K/MP3][57.16MB]