Python网络数据采集10:采集JavaScript

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

    在一定程度上,由于很难让所有浏览器开发商都认可同一个标准,所以客户端语言比服务器端语言要少很多。

    通常,你在网上遇到的客户端语言只有两种:ActionScript(开发Flash应用的语言)和JavaScript。今天ActionScript的使用率比10年前低很多,经常用于流媒体文件播放,用作在线游戏平台,或者是网站上那些没人想看更没有人点击的“介绍”页面。

10.1 JavaScript简介

     JavaScript是一种弱类型语言

     常用JavaScript库:用Python执行JavaScript代码的效率非常低,既费时有费力,尤其是在处理规模较大的JavaScript代码时,如果有绕过JavaScript并直接解析它的方法(不需要执行它就可以获得信息)会非常实用,可以帮你避开一大堆javaScript的麻烦事。

     1)jQuery:70%最流行的网站(约200万)和约30%的其他网站(约2亿)都在用,  “The State of jQuery 2014”

          <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>

     2)Google Analytics:有一半的网站都在用,如果一个网站使用了 Google Analytics 或其他类似的网络分析系统,而你不想让网站知道你在采集数据,就要确保把那些分析工具的 cookie 或者所有 cookie 都关掉

     3)Google地图:API

10.2 Ajax和动态HTML

    如果提交表单之后,或从服务器获取信息之后,网站的页面不需要重新刷新,那么你访问的网站就在用Ajax技术。Asynchronous JavaScript and XML(异步JavaScript和XML),网站不需要使用单独的页面请求就可以和网络服务器进行交互(收发信息)。和Ajax一样,动态HTML(DHTML)也是一系列用于解决网络问题的技术集合。比如,页面上的按钮只有当用户移动鼠标之后才出现,背景色可能每次点击都会改变,或者用一个Ajax请求触发页面加载一段新内容。

    那些使用了Ajax或DHTML技术改变/加载内容的页面,可能有一些采集手段,但是用Python解决这个问题只有两种途径:直接从JavaScript代码里采集内容,或者用Python的第三方库运行JavaScript,直接采集你在浏览器里看到的页面。

    在Python中用Selenium执行JavaScript

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

   PhantomJS(http://phantomjs.org/download.html)的工具代替真实的浏览器。一个“无头”浏览器。它会把网站加载到内存并执行页面上的JavaScript,但是它不会向用户展示网页的图形界面。

   wget https://bitbucket.org/ariya/phantomjs/downloads/phantomjs-2.1.1-linux-x86_64.tar.bz2

   你可以从 PyPI 网站(https://pypi.python.org/simple/selenium/)下载 Selenium 库

from selenium import webdriver
import time

driver = webdriver.PhantomJS(executable_path='phantomjs-2.1.1-linux-x86_64/bin/phantomjs')
driver.get("http://pythonscraping.com/pages/javascript/ajaxDemo.html")
time.sleep(3)  #等待加载时间
print(driver.find_element_by_id('content').text)
driver.close()

用id是loadedButton的按钮检测页面是不是已经完全加载:

from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium import webdriver
import time

driver = webdriver.PhantomJS(executable_path='phantomjs-2.1.1-linux-x86_64/bin/phantomjs')
driver.get("http://pythonscraping.com/pages/javascript/ajaxDemo.html")
try:
	element = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "loadedButton")))
finally:
	print(driver.find_element_by_id('content').text)
	driver.close()

10.3 处理重定向

     服务器端重定向一般都可以轻松地通过Python的urllib库解决,不需要使用Selenium,而客户端重定向却不能这样处理。它是有浏览器执行JavaScript完成的页面跳转,而不是服务器完成的跳转。

     示例http://pythonscraping.com/pages/javascript/redirectDemo2.html

     这个程序每半分钟检查一次网页,看看html标签还在不在,时限为10秒钟,不过检查的时间间隔和时限都可以根据实际情况随意调整。

from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
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='phantomjs-2.1.1-linux-x86_64/bin/phantomjs')
driver.get("http://pythonscraping.com/pages/javascript/redirectDemo1.html")
waitForLoad(driver)
print(driver.page_source)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值