目录

用Python写网络爬虫(4)-动态内容和表单交互

动态内容

逆向动态网页

依赖于AJAX的网站虽然看起来更加复杂,但是其结构促使数据和表现层分离,因此抽取数据时会更加容易。

通过网络请求抓包工具,查看AJAX请求,分析其模式,使用requests库模仿其请求模式,获得内容。一般来讲返回的都是xml或者json等序列化的数据,十分方便。

渲染动态网页

使用浏览器引擎渲染解析HTML、应用CSS样式并执行JavaScript语句,再从HTML中得到内容。

可以使用Selenium+PhantomJS配合在命令行中实现。

这里只演示selenium的用法(Chrome需要相应的驱动文件):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
from selenium import webdriver

# 这里可以换成PhantomJS
driver = webdriver.Chrome()

driver.get('http://example.webscraping.com/search')

# 填写表单内容
driver.find_element_by_id('search_term').send_keys('.')

# 使用JS直接设置表单内容,突破前端限制
js = "document.getElementById('page_size').options[1].text='1000'"
driver.execute_script(js)

# 模拟点击按钮,提交表单
driver.find_element_by_id('search').click()

# 至多等待30s,如果查询的元素没有出现,就抛出异常
driver.implicitly_wait(30)

links = dirver.find_elements_by_css_selector('#results a')
countries = [link.text for link in links]

如何选择动态网页抓取方式

浏览器渲染引擎帮助我们节省了了解网站后端工作原理的时间,但是该方法也有其劣势。渲染网页增加了开销,使其比单纯下载HTML更慢。另外,通常需要轮询网页来检查是否已经得到时间生成的HTML,这种方式非常脆弱,在网络较慢时经常会失败。

一般将浏览器引擎作为短期解决方案,此时长期的性能和可靠性并不算重要;而作为长期解决方案,应该尽最大努力对网站进行逆向工程。

表单交互

表单简介

form表单的几个重要设置:

  • action属性用于设置表单数据提交的地址,如果设置为#表示和登录表单相同的URL;
  • enctype属性用于设置数据提交的编码,例如application/x-www-form-urlencoded
  • method属性用于设置HTTP请求方法。
  • input标签的重要属性是name,用于设定提交到服务器端时某个域的名称。

表单**使用POST方法时,默认编码类型为application/x-www-form-urlencoded,**此时所有非字母数字类型的字符都需要转换为十六进制的ASCII值。但是,如果表单中包含大量非字母数字类型的字符时,**如上传二进制文件,这种编码类型的效率就会非常低,此时需要指定编码类型为multipart/form-data。**使用这种编码类型时,不会对输入进行编码,而是使用MIME协议将其作为多个部分进行发送,和邮件的传输标准相同。

提交表单

注意提交隐藏域和cookie,同时保持cookie和隐藏域中某些参数的一致。

也可以从浏览器中获取cookie,但是个人并不建议这样做,原因如下:

  1. 不同的操作系统不同浏览器cookie保存位置不一样,且可能会随浏览器发布新版本而改变;
  2. 可以用代码请求然后将cookie持久化存储,下次请求时先使用已保存的cookie,不行再重新请求,代码实现并不复杂,而且可以跨平台使用;

使用Mechanize模块实现自动化表单处理

Mechanize只支持Python2.x版本,GG。