Python数据网络采集5--处理Javascript和重定向
Python数据网络采集5--处理Javascript和重定向 到目前为止,我们与 Web 服务器通信的唯一方法是发送 HTTP 请求以获取页面。在某些网页中,我们可以在没有单个请求的情况下与 Web 服务器交互(发送和接收信息),因此该网页可能会使用 Ajax 技术来加载数据。使用之前的采集方式,我们可能只能采集加载前的数据,而无法掌握重要的数据。 与 Ajax 一样,动态 HTML (DHTM
Python数据网络采集5--处理Javascript和重定向
到目前为止,我们与 Web 服务器通信的唯一方法是发送 HTTP 请求以获取页面。在某些网页中,我们可以在没有单个请求的情况下与 Web 服务器交互(发送和接收信息),因此该网页可能会使用 Ajax 技术来加载数据。使用之前的采集方式,我们可能只能采集加载前的数据,而无法掌握重要的数据。
与 Ajax 一样,动态 HTML (DHTML) 也是一组用于解决网络问题的技术。 DHTML 使用客户端语言(例如 JavaScript)来控制页面的 HTML 元素。通常,当我们收集网站时,从浏览器中查看大内容与抓取道德内容不同。或者页面使用加载页面将我们引导到另一个页面,但 URL 链接在整个过程中保持不变。
这一切都是因为 Web 上的 JavaScript 犯了一个错误。浏览器可以正确执行 JavaScript,但我们可能会在爬取过程中直接忽略代码。所以你在浏览器中看到的和你爬到的不一样。
Ajax/DHTML 技术使爬虫变得困难,但 Selenium 可用于轻松处理页面中的 JavaScript 代码。
比如下面的页面使用Ajax技术加载,页面内容在2秒左右发生变化(但地址栏中的URL链接保持不变)。
进口请求
从 bs4 导入 BeautifulSoup
网址 \u003d 'http://pythonscraping.com/pages/javascript/ajaxDemo.html'
r \u003d requests.get(url)
汤 \u003d BeautifulSoup(r.text, 'lxml')
内容 \u003d soup.find('div', id\u003d'content')
打印(内容。字符串)
这是页面加载时会出现的一些内容。你不在乎刮这个。
Selenium 处理 JavaScript
事实上,如果你在浏览器中打开这个页面,你最后显示的不是这样的。它们最初会显示,但会立即被新内容替换。您可以尝试等待几秒钟。上面的示例使用 requests 访问,它立即返回响应,因此只能检索预加载的内容。因此,如果您等待,请求似乎也不起作用。去硒!
进口时间
从硒导入 webdriver
驱动程序 \u003d webdriver.PhantomJS(executable_path\u003dr'C:\Program Files (x86)\phantomjs\bin\phantomjs.exe')
driver.get('http://pythonscraping.com/pages/javascript/ajaxDemo.html')
# 等待加载完成
时间.sleep(5)
内容 \u003d driver.find_element_by_id('content').text
打印(内容)
驱动程序.quit()
这是您要检索的一些重要文本!
一键点击!
Phantom Js 是一款无界面浏览器,结合 Selenium 使用非常方便。 PhantomJs 需要下载。
这里是下载地址。
WebElement 有一个属性 text 来获取标签中的文本。看上面打印出来的信息,确实已经加载了新的内容。在使用中,需要指定phantomjs所在的目录。另外,因为没有界面,使用后记得关闭或退出。
上面的代码将元素的搜索限制在五秒内,但不确定页面何时能正常加载。因此,您可以不断检查页面的内容是否已加载。
从硒导入 webdriver
从 selenium.webdriver.support.wait 导入 WebDriverWait
从 selenium.webdriver.support 导入预期_conditions 作为 EC
从 selenium.webdriver.common.by 导入
驱动程序 \u003d webdriver.PhantomJS(executable_path\u003dr'C:\Program Files (x86)\phantomjs\bin\phantomjs.exe')
driver.get('http://pythonscraping.com/pages/javascript/ajaxDemo.html')
尝试:
元素 \u003d WebDriverWait(驱动程序, 10).until(EC.presence_of_element_located((By.ID, 'loadedButton')))
打印(元素)
最后:
打印(driver.find_element_by_id('content').text)
驱动程序.close()
<selenium.webdriver.remote.webelement.WebElement (sessionu003d"a300db00-6afa-11e7-9f0f-2189a7b4630b", elementu003d":wdc:1500301053057")>
这是您要检索的一些重要文本!
一键点击!
WebDriverWait 和 expected_conditions 用于构造隐式等待。隐式等待是等待 DOM 中的某个状态继续运行代码。没有显式的等待时间,但是有一个最大的等待时间(上例中为10s),而显式等待是指定等待时间,如上例指定sleep(5)。 expected_conditions 指定了期望的条件,上面的例子就是等到元素id加载完毕后,Button才会显示出来。 By是一个选择器,可以通过以下方式找到。
身份证\u003d“身份证”
XPATH \u003d "xpath"
LINK_TEXT \u003d "链接文本"
PARTIAL\LINK\TEXT \u003d "部分链接文本"
名称 \u003d "名称"
TAG_NAME \u003d "标签名称"
CLASS_NAME \u003d "类名"
CSS_SELECTOR \u003d "css 选择器"
其实下面两句话的意思是一样的:
driver.find\element(By.ID, '加载的按钮')
driver.findelement\by_id('加载的按钮')
Xpath语法
您还可以使用 Xpath 的语法进行查找。以下是一些常见的语法。
-
/ div选择根节点为div元素
-
// a 选择文档中的所有a节点(包括非根节点)
-
//@href 选择所有具有href属性的节点
-
// a[@hrefu003d'https://www.google.com'] 选择所有带有href的a标签作为谷歌网站
-
// a[3] 选择文档中的第三个a标签
-
// table[last()] 选择文档中的最后一个表
-
// a [position() < 3] 选择文档中的前三个a标签
处理重定向
重定向分为客户端重定向(Redirect)和服务端重定向(Dispatch),后者的意思是分派,也就是常说的转发。只转发一次请求,所以 Python 的请求可以轻松处理,但是如果重定向,请求两次,url 一般会发生变化。是时候使用 Selenium 了。下面的例子可以监控链接是否被重定向。使用的方法是从页面加载开始就监听 DOM 中的一个元素,然后重复调用该元素,直到抛出 StaleElement Reference Exception,即该元素不再在页面的 DOM 中,并且然后它跳了。
进口时间
# Stale 表示该元素不再出现在页面的 DOM 上
从 selenium.common.exceptions 导入 StaleElementReferenceException
从硒导入 webdriver
def 等待\for\load(a\driver):
元素 \u003d a_ driver.find_element_by_ tag\name('html')
打印('内容',元素)
计数 \u003d 0
当真:
计数 +u003d 1
# 超过10秒,直接返回
如果计数 > 20:
print('超时10秒后返回')
返回
time.sleep(0.5) # 检查是否是同一个元素。如果不是,则意味着 html 标签不再在 DOM 中。如果它没有抛出异常
new \u003d a_ driver.find_element_by_ tag\name('html')
打印('新',新)
如果元素 !u003d 新:
raise StaleElementReferenceException('刚刚重定向!')
驱动程序 \u003d webdriver.PhantomJS(r'C:\Program Files (x86)\phantomjs\bin\phantomjs.exe')
driver.get('https://pythonscraping.com/pages/javascript/redirectDemo1.html')
尝试:
等待\等待\加载(驱动程序)
除了 StaleElementReferenceException 为 e:
打印(e.msg)
最后:
打印(驱动程序.page_source)
内容 <selenium.webdriver.remote.webelement.WebElement (sessionu003d"e9c5e030-6b04-11e7-9cea-c913b202710e", elementu003d":wdc:1500305464563")>
新 <selenium.webdriver.remote.webelement.WebElement (sessionu003d"e9c5e030-6b04-11e7-9cea-c913b202710e", elementu003d":wdc:1500305464563")>
新 <selenium.webdriver.remote.webelement.WebElement (sessionu003d"e9c5e030-6b04-11e7-9cea-c913b202710e", elementu003d":wdc:1500305464563")>
新 <selenium.webdriver.remote.webelement.WebElement (sessionu003d"e9c5e030-6b04-11e7-9cea-c913b202710e", elementu003d":wdc:1500305464563")>
新 <selenium.webdriver.remote.webelement.WebElement (sessionu003d"e9c5e030-6b04-11e7-9cea-c913b202710e", elementu003d":wdc:1500305464563")>
新 <selenium.webdriver.remote.webelement.WebElement (sessionu003d"e9c5e030-6b04-11e7-9cea-c913b202710e", elementu003d":wdc:1500305464563")>
新 <selenium.webdriver.remote.webelement.WebElement (sessionu003d"e9c5e030-6b04-11e7-9cea-c913b202710e", elementu003d":wdc:1500305464563")>
新 <selenium.webdriver.remote.webelement.WebElement (sessionu003d"e9c5e030-6b04-11e7-9cea-c913b202710e", elementu003d":wdc:1500305468142")>
//刚刚重定向!
<html><头>
<title>目标页面!</title>
</head>
<正文>
这是您正在寻找的页面!
</body></html>
我们打印了刚刚进入网页的html元素对应的WebElement的wdc。 wdc:1500305464563 相当于一个id。
在一个循环中,不断检查它是否与原始WebElement相同,如果不是,则发生重定向。自重定向发生后,wdc 已更改。 wdc:1500305468142。页面跳转到redirectDemo1.html。
不要 @损害与
2017.7.17
更多推荐
所有评论(0)