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

Logo

学AI,认准AI Studio!GPU算力,限时免费领,邀请好友解锁更多惊喜福利 >>>

更多推荐