- Python 网页抓取教程
- Python 网页抓取 - 主页
- 介绍
- Python 入门
- 用于网页抓取的 Python 模块
- 网页抓取的合法性
- 数据提取
- 数据处理
- 处理图像和视频
- 处理文本
- 抓取动态网站
- 抓取基于表单的网站
- 处理验证码
- 使用刮刀进行测试
- Python 网页抓取资源
- Python 网页抓取 - 快速指南
- Python 网页抓取 - 资源
- Python 网页抓取 - 讨论
Python 网页抓取 - 动态网站
在本章中,让我们学习如何在动态网站上进行网页抓取以及详细涉及的概念。
介绍
网络抓取是一项复杂的任务,如果网站是动态的,复杂性就会成倍增加。根据联合国全球网络可访问性审计,超过 70% 的网站本质上是动态的,并且它们的功能依赖于 JavaScript。
动态网站示例
让我们看一个动态网站的例子,了解为什么它很难抓取。在这里,我们将以从名为http://example.webscraping.com/places/default/search 的网站进行搜索为例。但我们怎么能说这个网站是动态的呢?可以从以下 Python 脚本的输出来判断,该脚本将尝试从上述网页中抓取数据 -
import re import urllib.request response = urllib.request.urlopen('http://example.webscraping.com/places/default/search') html = response.read() text = html.decode() re.findall('(.*?)',text)
输出
[ ]
上面的输出显示示例抓取工具无法提取信息,因为我们尝试查找的 <div> 元素为空。
从动态网站抓取数据的方法
我们已经看到,抓取工具无法从动态网站中抓取信息,因为数据是通过 JavaScript 动态加载的。在这种情况下,我们可以使用以下两种技术从动态 JavaScript 相关网站中抓取数据 -
- JavaScript 逆向工程
- 渲染 JavaScript
JavaScript 逆向工程
称为逆向工程的过程将很有用,它可以让我们了解网页如何动态加载数据。
为此,我们需要单击指定 URL 的检查元素选项卡。接下来,我们将单击NETWORK选项卡以查找对该网页发出的所有请求,包括路径为/ajax的 search.json 。我们也可以借助以下 Python 脚本来完成此操作,而不是从浏览器或通过 NETWORK 选项卡访问 AJAX 数据 -
import requests url=requests.get('http://example.webscraping.com/ajax/search.json?page=0&page_size=10&search_term=a') url.json()
例子
上面的脚本允许我们使用 Python json 方法访问 JSON 响应。同样,我们可以下载原始字符串响应,并使用 python 的 json.loads 方法,我们也可以加载它。我们在以下 Python 脚本的帮助下完成此操作。它基本上会通过搜索字母表中的字母“a”来抓取所有国家/地区,然后迭代 JSON 响应的结果页面。
import requests import string PAGE_SIZE = 15 url = 'http://example.webscraping.com/ajax/' + 'search.json?page={}&page_size={}&search_term=a' countries = set() for letter in string.ascii_lowercase: print('Searching with %s' % letter) page = 0 while True: response = requests.get(url.format(page, PAGE_SIZE, letter)) data = response.json() print('adding %d records from the page %d' %(len(data.get('records')),page)) for record in data.get('records'):countries.add(record['country']) page += 1 if page >= data['num_pages']: break with open('countries.txt', 'w') as countries_file: countries_file.write('n'.join(sorted(countries)))
运行上述脚本后,我们将得到以下输出,记录将保存在名为country.txt的文件中。
输出
Searching with a adding 15 records from the page 0 adding 15 records from the page 1 ...
渲染 JavaScript
在上一节中,我们在网页上进行了逆向工程,了解 API 的工作原理以及如何使用它在单个请求中检索结果。然而,我们在进行逆向工程时可能会面临以下困难 -
有时网站可能非常困难。例如,如果网站是使用 Google Web Toolkit (GWT) 等高级浏览器工具制作的,那么生成的 JS 代码将是机器生成的,难以理解和逆向工程。
一些更高级别的框架(例如React.js)可以通过抽象已经复杂的 JavaScript 逻辑来使逆向工程变得困难。
解决上述困难的方法是使用浏览器渲染引擎来解析 HTML、应用 CSS 格式并执行 JavaScript 来显示网页。
例子
在此示例中,为了渲染 Java 脚本,我们将使用熟悉的 Python 模块 Selenium。以下 Python 代码将在 Selenium 的帮助下渲染网页 -
首先,我们需要从 selenium 导入 webdriver,如下所示 -
from selenium import webdriver
现在,提供我们根据要求下载的网络驱动程序的路径 -
path = r'C:\\Users\\gaurav\\Desktop\\Chromedriver' driver = webdriver.Chrome(executable_path = path)
现在,提供我们想要在由 Python 脚本控制的 Web 浏览器中打开的 url。
driver.get('http://example.webscraping.com/search')
现在,我们可以使用搜索工具箱的ID来设置要选择的元素。
driver.find_element_by_id('search_term').send_keys('.')
接下来,我们可以使用java脚本设置选择框内容,如下所示 -
js = "document.getElementById('page_size').options[1].text = '100';" driver.execute_script(js)
以下代码行显示已准备好在网页上单击搜索 -
driver.find_element_by_id('search').click()
下一行代码显示它将等待 45 秒来完成 AJAX 请求。
driver.implicitly_wait(45)
现在,为了选择国家/地区链接,我们可以使用 CSS 选择器,如下所示 -
links = driver.find_elements_by_css_selector('#results a')
现在可以提取每个链接的文本以创建国家/地区列表 -
countries = [link.text for link in links] print(countries) driver.close()