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

被称为逆向工程的过程将是有用的,让我们了解数据是如何被网页动态加载的。

为了做到这一点,我们需要点击指定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.load方法,我们也可以加载它。我们是在以下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 Script,我们将使用一个熟悉的Python模块Selenium。下面的Python代码将在Selenium的帮助下渲染一个网页-

首先,我们需要从Selenium导入webdriver,如下所示

from selenium import webdriver

现在,根据我们的要求,提供我们已经下载的网络驱动器的路径

path = r'C:\\Users\\gaurav\\Desktop\\Chromedriver'
driver = webdriver.Chrome(executable_path = path)

现在,提供我们想在网络浏览器中打开的网址,现在由我们的Python脚本控制。

driver.get(['http://example.webscraping.com/search'](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()

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程