Python网络数据采集之采集JavaScript|第09天

了解JavaScript;

使用selenium库和phantomjs

采集JavaScript

客户端脚本语言是运行在浏览器而非服务器上的语言。客户端语言成功的前提是浏览器拥有正确地解释和执行这类语言的能力。

到目前为止,JavaScript 是网络上最常用也是支持者最多的客户端脚本语言。它可以收集 用户的跟踪数据,不需要重载页面直接提交表单,在页面嵌入多媒体文件,甚至运行网页游戏。那些看起来非常简单的页面背后通常使用了许多 JavaScript 文件。

例如:

1
2
3
<script type="text/javascript" >
alert("这是一个JavaScript的文件!")
<script>

JavaScript简介

几个关键字了解一下:弱类型语言,其他语言有的基本都有。JavaScript里所有的变量都用 var关键词字进行定义,可以把函数作为变量使用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<script>
var fibonacci = function() {
var a = 1;
var b = 1;
return function() {
var temp = b; b = a + b;
a = temp; return b;
} }

var fibInstance = fibonacci();
console.log(fibInstance()+" is in the Fibonacci sequence");
console.log(fibInstance()+" is in the Fibonacci sequence");
console.log(fibInstance()+" is in the Fibonacci sequence");
</script>

上面的例子看一下就好,熟悉一下就可以,就是这么简单。

常用的JavaScript库有很多。例如jQuery,Google Analytics,React等等,了解一下。

Ajax和动态HTML

与网站服务器通信的唯一方式,就是发出HTTP请求获取新页面,如果提交表单之后,或从服务器获取信息之后,网站的页面不需要重新刷新,那么你访问的网站就在用Ajax 技术。

Ajax全称是Asynchronous JavaScript and XML(异步 JavaScriptXML),网站不需要使用单独的页面请求就可以和网络服务器进行交互 (收发信息)。

Python中用Selenium执行JavaScriptSelenium是一个强大的网络数据采集工具,其最初是为网站自动化测试而开发的。近几年,它还被广泛用于获取精确的网站快照,因为它们可以直接运行在浏览器上。Selenium可以让浏览器自动加载页面,获取需要的数据,甚至页面截屏,或者判断网站上某些动作是否发生。Selenium 自己不带浏览器,它需要与第三方浏览器结合在一起使用。

我们可以用一个叫PhantomJS的工具代替真实的浏览器。PhantomJS 是一个“无头”(headless)浏览器。它会把网站加载到内存并执行页面上的 JavaScript,但是它不会向用户展示网页的图形界面。把 SeleniumPhantomJS 结合在一 起,就可以运行一个非常强大的网络爬虫了,可以处理 cookieJavaScripheader,以及任何你需要做的事情。

安装Selenium可以去其官网下载安装,也可以直接pip来安装这个库,非常简单。但是PhantomJS不是库,不能直接用pip安装,可以直接去官网下载页面下载安装,同时如果你是Mac的用户可以通过homebrew安装:

1
brew install phantomjs

Selenium 库是一个在 WebDriver 上调用的 APIWebDriver 有点儿像可以加载网站的浏览器,但是它也可以像 BeautifulSoup 对象一样用来查找页面元素,与页面上的元素进行交互 (发送文本、点击等),以及执行其他动作来运行网络爬虫。

1
2
3
4
5
6
7
8
from selenium import webdriver
import time

driver = webdriver.PhantomJS(executable_path='/usr/local/Cellar/phantomjs/2.1.1/bin/phantomjs') #创建了一个新的Selenium WebDriver,需要指定自己的phantomjs路径
driver.get("http://pythonscraping.com/pages/javascript/ajaxDemo.html") #用WebDriver加载页面
time.sleep(3) #暂停3秒执行
print(driver.find_element_by_id('content').text) #查看页面内容
driver.close()

处理重定向

客户端重定向是在服务器将页面内容发送到浏览器之前,由浏览器执行 JavaScript 完成的 页面跳转,而不是服务器完成的跳转。当使用浏览器访问页面的时候,有时很难区分这两种重定向。由于客户端重定向执行很快,加载页面时你甚至感觉不到任何延迟,所以会让你觉得这个重定向就是一个服务器端重定向。

服务端重定向可以通过urllib库来解决,但是客户端的重定向不能这样处理。Selenium 可以执行这种 JavaScript 重定向,和它处理其他 JavaScript 的方式一样;但是这类重定向的主要问题是什么时候停止页面监控,也就是说,怎么识别一个页面已经完成重定向。

我们可以用一种智能的方法来检测客户端重定向是否完成,首先从页面开始加载 时就“监视”DOM 中的一个元素,然后重复调用这个元素直到 Selenium 抛出一个StaleElementReferenceException 异常;也就是说,元素不在页面的 DOM 里了,说明这时网站已经跳转:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
from selenium import webdriver
import time
from selenium.webdriver.remote.webelement import WebElement
from selenium.common.exceptions import StaleElementReferenceException

def waitForLoad(driver):
elem = driver.find_element_by_tag_name("html")
count = 0
while True:
count += 1
if count > 20:
print("Timing out after 10 seconds and returning")
return
time.sleep(.5)
try:
elem == driver.find_element_by_tag_name("html")
except StaleElementReferenceException:
return

driver = webdriver.PhantomJS(executable_path='drivers/phantomjs/phantomjs-2.1.1-macosx/bin/phantomjs')
driver.get("http://pythonscraping.com/pages/javascript/redirectDemo1.html")
waitForLoad(driver)
print(driver.page_source)
一分支持,也是鼓励!
0%