这篇文章给大家聊聊关于深度解读:65.1现象背后的经济与社会影响,以及对应的知识点,希望对各位有所帮助,不要忘了收藏本站哦。
总结:显示等待:满足条件后才会处理网页;
隐示等待:设置等待时间;注意: 搜索框 是元组元素=WebDriverWait(驱动程序, 10).until(
EC.presence_of_element_ located( # 元素已加载到DOM 中,但不保证可见;
(By.ID, "inp-query") # 查找搜索框是一个元组
) 显式等待比隐式等待节省执行时间,因此更推荐使用显式等待来判断页面元素是否存在。
动态网页处理
许多网站使用AJAX技术、SPA技术,部分内容都是异步动态加载的。可以提高用户体验、减少不必要的流量、方便CDN加速等(大部分网页,尤其是手机端)
但爬虫程序爬取的HTML页面就相当于一个页面模板,动态内容不在其中。
一种解决方案是,我们是否可以构建一个包含JS 引擎的浏览器,让它加载网页并与网站交互。我们进行编程以从此浏览器获取内容,包括动态内容。该浏览器不需要用户交互界面,只要能支持HTTP、HTTPS协议和服务器端交互,能解析HTML、CSS、JS就行了。
1. PhantomJS
headless无头浏览器,支持Javascript。可以在Windows、Linux、Mac OS等操作系统上运行。
所谓无头浏览器,就是包含JS引擎、浏览器布局引擎等核心组件,但不具备与用户交互的界面的浏览器。
官网http://phantomjs.org/
官方文档http://phantomjs.org/
下载http://phantomjs.org/
下载操作系统对应的Phantomjs,解压后使用;
测试:判断是否安装成功;
//测试.js
"使用严格";
console.log("你好世界");
幻影.exit();
$ phantomjs-2.1.1-windowsbinphantomjs.exe test.js
hello world #运行成功;
# 自带试运行示例;
$ phantomjs-2.1.1-windowsbinphantomjs.exe phantomjs-2.1.1-windowsexampleshello.js
你好世界!
$ phantomjs-2.1.1-windowsbinphantomjs.exe phantomjs-2.1.1-windowsexamplesversion.js
使用PhantomJS 版本2.1.1
2. Selenium
这是WEB自动化测试工具。它可以直接在浏览器支持主流的浏览器中运行,包括PhantomJS(无头浏览器)。动作测试:
官网https://www.seleniumhq.org/
安装
$ pip install seleniumWebDriver 你可以看一下
chrom浏览器web driver(chromedriver.exe),可通过以下网址访问:
http://npm.taobao.org/mirrors/chromedriver/
firefox(Firefox)web driver (geckodriver.exe)访问此处:
https://github.com/mozilla/geckodriver/releases
其他浏览器驱动程序可以在下面的列表中找到:
Edge:https://developer.microsoft.com/en-us/micrsosft-edage/tools/webdriver
Safari:https://webkit.org/blog/6900/webdriver-support-in-safari-10/
部分Chromedriver支持的Chrome版本对照表:
chromedriver版本支持的Chrome版本
v2.41 v67-69
v2.40 v66-68
v2.39 v66-68
v2.38 v65-67
v2.37 v64-66
v2.36 v63-65
v2.35 v62-64
v2.34 v61-63
v2.33 v60-62
v2.32 v59-61
v2.31 v58-60
v2.30 v58-60
v2.29 v56-58
v2.28 v55-57
v2.27 v54-56
v2.26 v53-55
v2.25 v53-55
v2.24 v52-54
v2.23 v51-53
v2.22 v49-52
v2.21 v46-50
3. 开发实战
不同的浏览器会提供操作界面。 Selenium 使用这些接口来操作浏览器。
Selenium的核心对象是webdriver,通过它可以操作浏览器、截图、HTTP访问、解析HTML等。
从selenium.webdriver 导入PhantomJS
driver=PhantomJS("F:/BaiduNetdiskDownload/2019 Python网络学期配套资料/slides/chapter16爬虫/install/phantomjs-2.1.1-windows/bin/phantomjs.exe")
driver.set_window_size(1280,1080)
driver.get("https://www.baidu.com/?tn=78000241_5_hao_pg")
driver.save_screenshot("F:/test/screen-baidu.png")
#------------------------------------------------ - ---------
# 一般使用无头浏览器并忽略警告;
UserWarning: Selenium 对PhantomJS 的支持已被弃用,请改用Chrome 或Firefox 的无头版本
warnings.warn("Selenium 对PhantomJS 的支持已被弃用,请使用headless "
1. 处理异步请求
Bing 的查询结果是通过异步请求返回的,因此直接访问页面无法直接获取搜索结果。
. 定位页面中的内容是否返回成功来自urllib 导入解析
从selenium.webdriver 导入PhantomJS
导入日期时间、时间、随机
# #如果环境变量中没有指定PhantomJS位置
driver=PhantomJS("F:/BaiduNetdiskDownload/2019 Python网络学期配套资料/slides/chapter16爬虫/install/phantomjs-2.1.1-windows/bin/phantomjs.exe")
driver.set_window_size(1280,1080)
# 保存图片;
def savepic():
基本路径="F:/测试/"
文件名="{:%Y%m%d%H%M%S}-{:03}.png".format(datetime.datetime.now(), random.randint(1,100))
driver.save_screenshot(基本路径+文件名)
# 生成页面快照并保存
# 模拟浏览器输入URL;
url="https://cn.bing.com/search?q=%E9%A9%AC%E5%93%A5%E6%95%99%E8%82%B2" #自动转入;
# url="https://cn.bing.com/search?" + parse.urlencode({"q":"马哥教育"}) # parse.urlencode 转换字符;
driver.get(url) # get方法会等到页面加载完毕后才继续执行程序。通常测试会在这里选择time.sleep(2)
最大重试次数=5
对于我在范围内(MAXRETRIES):
尝试:
ele=driver.find_element_by_id("b_results")
print(i, ele.is_displayed()) #元素不可见;
如果notele.is_displayed():
时间.睡眠(1)
继续
保存图片()
#break#正常加上break;
除了异常e:
打印(类型(e),e)
打印(" - - - - - - - - - - ")
驱动程序.quit()
#----------------------------------------------------
0 错误
1 True #页面内容成功返回;
2正确
3 真实
4 true 可能看不到结果,说明数据回来了,整理好了,但是没有显示出来。
您可以添加代码来确定元素是否显示,直到等待数据呈现在页面上;
2.下拉框处理
Selenium专门提供了Select类来处理网页(下拉一次,整个页面重新刷新一次,效率低下)中的下拉框,但是下拉框用在越来越少的页面上。这次我使用https://www.oschina.net/search?scope=projectq=python
select 下拉框的处理
select下拉框from disk cache或者from memory cache又是在什么情况下会出现呢?从字面意思上不难理解。这是浏览器的缓存机制。磁盘从硬盘读取资源,而内存从内存获取资源。两者的区别就是内存和硬盘的区别:内存中的资源是暂时的,当页面关闭或者刷新时就会丢失;而disk则存放在硬盘上,可以在文件夹中找到。
那是不是意味着下载加载页面时需要从服务器获取内存中的资源呢?事实上,情况并非如此。内存中的资源也会存储在磁盘中,因此下次加载时,浏览器会先从磁盘中检索。
刷新请求,表示从服务器重新下载磁盘缓存;
表单控件selectfrom urllib import parse
从selenium.webdriver 导入PhantomJS
from selenium.webdriver.support.ui import Select # 在webdriver.support.ui 下查找Select;
导入日期时间、时间、随机
# #如果环境变量中没有指定PhantomJS位置
driver=PhantomJS("F:/BaiduNetdiskDownload/2019 Python网络学期配套资料/slides/chapter16爬虫/install/phantomjs-2.1.1-windows/bin/phantomjs.exe")
driver.set_window_size(1280,1080)
# 保存图片;
def savepic():
基本路径="F:/测试/"
文件名="{:%Y%m%d%H%M%S}-{:03}.png".format(datetime.datetime.now(), random.randint(1,100))
driver.save_screenshot(基本路径+文件名)
# 生成页面快照并保存
# 模拟浏览器输入URL;
url="https://www.oschina.net/search?scope=project"
# url="https://cn.bing.com/search?" + parse.urlencode({"q":"马哥教育"}) # parse.urlencode 转换字符;
driver.get(url) # get方法会等到页面加载完毕后才继续执行程序。通常测试会在这里选择time.sleep(2)
打印(1,驱动程序.current_url)
保存图片()
# 如何使用模拟选择框;
sel=driver.find_element_by_name("tag1")
ele=选择(sel)
ele.select_by_value("309")
#ele.按索引选择(1)
打印(2,驱动程序.current_url)
保存图片()
driver.quit()
3. 模拟键盘操作(模拟登陆)
Web 驱动程序提供了一系列find 方法供用户获取网页中的元素。 Element 对象可以使用send_keys 模拟键盘输入。
oschina登录页面登录成功后会跳转至首页。会员信息将显示在主页右上角。如果您未登录,则不会有此类信息。
在浏览器中 模拟登录过程:
分别包括:打开登录页面的截图;输入账号截图;登录成功截图,获取cookies,可以随时登录;
从urllib 导入解析
从selenium.webdriver 导入PhantomJS
从selenium.webdriver.support.ui 导入选择
从selenium.webdriver.common.keys 导入密钥
导入日期时间、时间、随机
# #如果环境变量中没有指定PhantomJS位置
driver=PhantomJS("F:/BaiduNetdiskDownload/2019 Python网络学期配套资料/slides/chapter16爬虫/install/phantomjs-2.1.1-windows/bin/phantomjs.exe")
driver.set_window_size(1280,1080)
# 保存图片;
def savepic():
基本路径="F:/测试/"
文件名="{:%Y%m%d%H%M%S}-{:03}.png".format(datetime.datetime.now(), random.randint(1,100))
driver.save_screenshot(基本路径+文件名)
# 生成页面快照并保存
# 模拟浏览器登录URL;
url="https://www.oschina.net/home/login"
# url="https://cn.bing.com/search?" + parse.urlencode({"q":"马哥教育"}) # parse.urlencode 转换字符;
driver.get(url) # get方法会等到页面加载完毕后才继续执行程序。通常测试会在这里选择time.sleep(2)
打印(1,驱动程序.current_url)
savepic() #打开登录页面截图;
# 如何使用模拟选择框;
用户名=driver.find_element_by_name("用户名")
用户名.send_keys("")
用户名=driver.find_element_by_name("密码")
用户名.send_keys("")
# driver.find_element_by_class_name()
savepic() # 输入账户截图
密码.send_keys(Keys.ENTER)
时间.睡眠(1)
savepic() # 登录成功的截图或者添加验证,验证是否有退出按钮;
打印(2,驱动程序.current_url)
cookies=driver.get_cookies() #
print(cookies,type(cookies)) # 会有key: oscpid
驱动程序.quit()
#----------------------------------
如果登录成功就会有oscpid;
获得cookies 登录后 爬取页面
# 登录后获取cookie并抓取页面。
导入请求
从requests.cookies 导入RequestsCookieJar
从fake_useragent 导入UserAgent
headers={"User-agent":UserAgent().random}
# 没有cookies
响应=requests.request("GET", url, headers=headers)
文本=响应.文本
print(response.url) # 如果url中有login,则表示尚未登录;
print("============================================")
#cookies#收集cookies字典;
jar=RequestsCookieJar()
对于cookies: 中的cookies
jar.set(cookies.get("name"), cookies.get=("value")) # 获取cookies字典;
响应=requests.request("GET", url, headers=headers, cookies=jar)
文本=响应.文本
print(response.url) # url中没有登录,登录成功。
# 登录后保存html
open("./cnblog-html.html","w",encoding="UTF-8") as f:
f.write(text)验证码的问题不是重点;取决于AI模型的成功率;
4. 页面等待技术
越来越多的页面使用Ajax等异步加载技术,会导致代码中要访问的页面元素在加载之前就被访问(循环),抛出异常。
方法1 线程休眠
使用time.sleep(n) 等待数据加载。
配合循环,等待数据加载完毕,可以解决动态加载或者很多页面加载缓慢的问题。当然,您可以设置最大重试次数以避免永远循环。请参阅这篇文章“处理异步请求”
方法2 Selenium等待
Selenium的等待分为:显示等待 和 隐式等待隐式等待,等待特定时间
显式等待,指定一个条件,等待条件满足才继续执行。还可以设置超时,超时就会抛出异常。
参考:https://www.selenium.dev/documentation/en/
#官网案例:
从硒导入网络驱动程序
从selenium.webdriver.common.by 导入
从selenium.webdriver.common.keys 导入密钥
从selenium.webdriver.support.ui 导入WebDriverWait
从selenium.webdriver.support.expected_conditions 导入Presence_of_element_ located
#此示例需要Selenium WebDriver 3.13 或更高版本
使用webdriver.Firefox() 作为driver:
等待=WebDriverWait(驱动程序, 10)
driver.get("https://google.com/ncr")
driver.find_element(By.NAME, "q").send_keys("cheese" + Keys.RETURN)
first_result=wait.until(presence_of_element_ located(By.CSS_SELECTOR, "h3div"))
打印(first_result.get_attribute("textContent"))
#------------------------------------------------ - ----------------------------------------------------
从硒导入网络驱动程序
从selenium.webdriver.common.by 导入
从selenium.webdriver.common.keys 导入密钥
从selenium.webdriver.support.ui 导入WebDriverWait
从selenium.webdriver.support.expected_conditions 导入EC
导入日期时间、时间、随机
# #如果环境变量中没有指定PhantomJS位置
driver=PhantomJS("F:/BaiduNetdiskDownload/2019 Python网络学期配套资料/slides/chapter16爬虫/install/phantomjs-2.1.1-windows/bin/phantomjs.exe")
驱动程序.set_window_size(1280,108
0) # 保存图片; def savepic(): basepath = "F:/test/" filename = "{:%Y%m%d%H%M%S}-{:03}.png".format(datetime.datetime.now(), random.randint(1,100)) driver.save_screenshot(basepath+filename) # 生成页面快照并保存 url = "" driver.get(url) driver.find_element(By.ID, "inp-qury") try: element = WebDriverWait(driver, 10) .until( EC.presence_of_element_locate( # 元素加载到DOM,但是不保证他是可见的; (By.ID, "myDynamicElement") ) ) finally: driver.quit()表单 expected_conditionsn内置条件说明title_is判断当前页面的title是否精确等于预期title_contains判断当前页面的title是否包含预期字符串presence_of_element_located判断某个元素是否被加到了dom树里,并不代表该元素一定可见visibility_of_element_located判断某个元素是否可见。可见代表元素非隐藏,并且元素的宽和高都不等于0visibility_of跟上面的方法做一样的事情,只是上面的方法要传入locator,这个方法直接传定位到的element就好了presence_of_all_elements_located判断是否至少有1个元素存在于dom树中。举个例子,如果页面上有n个元素的class都是"column-md-3",那么只要有1个元素存在,这个方法就返回Truetext_to_be_present_in_element判断某个元素中的text是否包含了预期的字符串text_to_be_present_in_element_value判断某个元素中的value属性是否包含了预期的字符串frame_to_be_available_and_switch_to_it判断该frame是否可以switch进去, 如果可以的话, 返回True 且switch进去, 否则返回Falseinvisibility_of_element_located判断某个元素中是否不存在于dom树或不可见element_to_be_clickable判断某个元素中是否可见并且是enable的, 这样的话才叫clickablestaleness_of等某个元素从dom树中移除, 注意, 这个方法也是返回True或 Falseelement_to_be_selected判断某个元素是否被选中了,一般用在下拉列表element_selection_state_to_be判断某个元素的选中状态是否符合预期element_located_selection_state_to_be跟上面的方法作用一样,只是上面的方法传入定位到的element, 而这个方法传入locatoralert_is_present判断页面上是否存在alert显示等待结合WebDriverWait和expected_conditions判断元素是否存在, 每间隔1秒判断一次,10s超时,存在返回True,不存返回FalseWebDriverWait类提供方法:(1)until(method, message="") 在规定时间内,每隔一段时间调用一下method方法,至到期返回值不为False,如果超时抛出带有message的TimeoutException异常信息 (1)until_not(method, message="") 与until()方法相反,表示在规定时间内,每隔一段时间调用一下method方法,至到期返回值为False,如果超时抛出带有message的TimeoutException异常信息:param locator: locator为元组类型,如("id", "kw")定位搜索框,搜索电影; url中 要调取的框子 from selenium import webdriver from selenium.webdriver import PhantomJS # 使用无头浏览器 from selenium.webdriver.common.by import By # 键盘操作 from selenium.webdriver.common.keys import Keys # 负责操作界面; from selenium.webdriver.support.ui import WebDriverWait # 负责循环等待 from selenium.webdriver.support import expected_conditions as EC # 负责条件触发; import datetime, time, random # #如果没有在环境变量指定PhantomJS位置 driver = PhantomJS("F:/BaiduNetdiskDownload/2019 Python网络期班配套资料/slides/chapter16爬虫/install/phantomjs-2.1.1-windows/bin/phantomjs.exe") driver.set_window_size(1280,1080) # 保存图片; def savepic(): basepath = "F:/test/" filename = "{:%Y%m%d%H%M%S}-{:03}.png".format(datetime.datetime.now(), random.randint(1,100)) driver.save_screenshot(basepath+filename) # 生成页面快照并保存 url = "https://movie.douban.com/" driver.get(url) # element = driver.find_element(By.ID, "inp-qury") # 找到搜索框 1; # 在10s内, 定位元素inp-query , 元素加载到DOM,但是不保证他是可见的; try: element = WebDriverWait(driver, 10).until( EC.presence_of_element_located( # 元素加载到DOM,但是不保证他是可见的; (By.ID, "inp-query") # 找搜索框 是 元组 ) ) element.send_keys("TRON") element.send_keys(Keys.ENTER) print(driver.current_url) savepic() except Exception as e: print(type(e), e) finally: driver.quit() #---------------------------------------------------- C:ProgramDataMiniconda3envsbloglibsite-packagesseleniumwebdriverphantomjswebdriver.py:49: UserWarning: Selenium support for PhantomJS has been deprecated, please use headless versions of Chrome or Firefox instead warnings.warn("Selenium support for PhantomJS has been deprecated, please use headless " https://search.douban.com/movie/subject_search?search_text=TRON&cat=1002 #搜索网页;隐式等待找不到这个元素,继续等10s,还是找不到元素,结束程序; from selenium import webdriver from selenium.webdriver import PhantomJS # 使用无头浏览器 from selenium.webdriver.common.by import By # 键盘操作 from selenium.webdriver.common.keys import Keys # 负责操作界面; from selenium.webdriver.support.ui import WebDriverWait # 负责循环等待 from selenium.webdriver.support import expected_conditions as EC # 负责条件触发; import datetime, time, random # #如果没有在环境变量指定PhantomJS位置 driver = PhantomJS("F:/BaiduNetdiskDownload/2019 Python网络期班配套资料/slides/chapter16爬虫/install/phantomjs-2.1.1-windows/bin/phantomjs.exe") driver.implicitly_wait(10) # 拿到driver等10s driver.set_window_size(1280,1080) # 保存图片; def savepic(): basepath = "F:/test/" filename = "{:%Y%m%d%H%M%S}-{:03}.png".format(datetime.datetime.now(), random.randint(1,100)) driver.save_screenshot(basepath+filename) # 生成页面快照并保存 url = "https://movie.douban.com/" driver.get(url) # 等 10s, 元素加载到DOM树,找id=inp-query try: element = driver.find_element(By.ID, "inp-query") # 找到搜索框 1; # element = WebDriverWait(driver, 1).until( # EC.presence_of_element_located( # 元素加载到DOM,但是不保证他是可见的; # (By.ID, "inp-query") # 找搜索框 是 元组 # ) # ) element.send_keys("TRON") element.send_keys(Keys.ENTER) print(driver.current_url) # 新的url; savepic() except Exception as e: print(type(e), e) finally: driver.quit() #---------------------------------- https://search.douban.com/movie/subject_search?search_text=TRON&cat=1002Message: {"errorMessage":"Unable to find element with id "inp-qu1ery"","request":{"headers":{"Accept":"application/json","Accept-Encoding":"identity","Content-Length":"91","Content-Type":"application/json;charset=UTF-8","Host":"127.0.0.1:4483","User-Agent":"selenium/3.141.0 (python windows)"},"httpVersion":"1.1","method":"POST","post":"{"using": "id", "value": "inp-qu1ery", "sessionId": "bb714600-ed9e-11ea-bb6d-6b286a00b9a6"}","url":"/element","urlParsed":{"anchor":"","query":"","file":"element","directory":"/","path":"/element","relative":"/element","port":"","host":"","password":"","user":"","userInfo":"","authority":"","protocol":"","source":"/element","queryKey":{},"chunks":["element"]},"urlOriginal":"/session/bb714600-ed9e-11ea-bb6d-6b286a00b9a6/element"}} Screenshot: available via screen总结
Selenium的Web Driver是其核心, 从Selenium 2开始就是最重要的编程核心对象, 在Selenium 3中更是如此。深度解读:65.1现象背后的经济与社会影响和的问题分享结束啦,以上的文章解决了您的问题吗?欢迎您下次再来哦!
【深度解读:65.1现象背后的经济与社会影响】相关文章:
2.米颠拜石
3.王羲之临池学书
8.郑板桥轶事十则
用户评论
这数字让人有点困惑,是百分比吗?
有20位网友表示赞同!
是不是某种统计数据?我很想知道具体指的是什么领域。
有9位网友表示赞同!
这么奇怪的数字,不会是实验结果吗?
有5位网友表示赞同!
这看起来像是某个分数或成绩吧?
有18位网友表示赞同!
感觉像是一台机器读出的数据,缺乏上下文信息。
有14位网友表示赞同!
65.1 点多少分?需要知道标注的范围才能理解。
有9位网友表示赞同!
是不是应该再加上一些数字说明,例如“人口增长率为65.1%”?
有12位网友表示赞同!
65.1 这个数字很有意思,让我好奇背后的故事。
有10位网友表示赞同!
这个数字代表着什么价值?我很想了解一下。
有8位网友表示赞同!
看到这数字,我第一反应是温度或某种物理量。
有10位网友表示赞同!
感觉像是某个考试成绩,有点低吧?
有9位网友表示赞同!
想知道65.1 这个数字的来源和意义。
有7位网友表示赞同!
这种特殊的格式让我感到好奇,是有什么特殊符号吗?
有13位网友表示赞同!
是不是某个产品的价格或者折扣力度?
有5位网友表示赞同!
感觉像是科研项目进度汇报里的数据点。
有11位网友表示赞同!
这个数字太抽象了,需要更多信息才能理解它的含义。
有6位网友表示赞同!
65.1 这个数字会带来什么影响?期待进一步的解读。
有18位网友表示赞同!
是不是某个时间戳或者信号强度数值?
有19位网友表示赞同!
感觉像是金融市场数据中的一个指标。
有9位网友表示赞同!