在本章中,让无涯教程学习如何在动态网站上执行Web抓取示例。
动态网站示例
让无涯教程看一个动态网站的示例,了解为什么很难抓取,在这里将以从http://example.webscraping.com/places/default/search 述网页中抓取数据-
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 标签,以查找对该网页发出的所有请求,包括search.json,其路径为/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的工作方式以及如何使用它在单个请求中检索输出,但是在进行逆向工程时会面临以下困难-
有时网站可能非常困难,如果网站是使用高级浏览器工具构建的,则生成的JS代码将是机器生成的,难以理解和反向工程。
某些更高级的框架,如 React.js ,可能会通过抽象化已经很复杂的JavaScript逻辑而使逆向工程变得困难。
解决上述难题的方法是使用浏览器呈现引擎来解析HTML,应用CSS格式并执行JavaScript以显示网页。
在此示例中,将使用熟悉的Python模块Selenium,以下Python代码将在Selenium的帮助下呈现网页-
首先,需要从Selenium中导入webdriver,如下所示:
from selenium import webdriver
现在,提供根据要求下载的Web驱动程序的路径-
path=r'C:\\Users\\gaurav\\Desktop\\Chromedriver' driver=webdriver.Chrome(executable_path=path)
现在,提供要在该Web浏览器中打开的URL,该URL现在由Python脚本控制。
driver.get('http://example.webscraping.com/search')
现在,可以使用搜索ID来设置要选择的元素。
driver.find_element_by_id('search_term').send_keys('.')
接下来,无涯教程可以使用javascript来设置选择框的内容,如下所示:
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()
参考链接
https://www.learnfk.com/python-web-scraping/python-web-scraping-dynamic-websites.html