ajax抓取网页内容(本篇文章我们来研究一下怎么分析网页的Ajax请求(图))

优采云 发布时间: 2022-02-25 16:11

  ajax抓取网页内容(本篇文章我们来研究一下怎么分析网页的Ajax请求(图))

  在本文文章中,我们将研究如何分析网页的Ajax请求。

  我们平时爬网页的时候,可能会遇到一些网页直接请求的HTML代码,并没有我们需要的数据,也就是我们在浏览器中看到的内容。

  这是因为信息是通过 Ajax 加载并通过 js 渲染生成的。这时,我们需要分析这个网页的请求。

  什么是阿贾克斯

  AJAX 代表“Asynchronous Javascript And XML”(异步 JavaScript 和 XML),指的是一种用于创建交互式 Web 应用程序的 Web 开发技术。

  AJAX = 异步 JavaScript 和 XML(标准通用标记语言的子集)。

  AJAX 是一种用于创建快速和动态网页的技术。

  AJAX 是一种无需重新加载整个网页即可更新部分网页的技术。

  简单地说,就是加载了网页。浏览器地址栏中的 URL 没有改变。是javascript异步加载的网页,应该是ajax。AJAX一般通过XMLHttpRequest对象接口发送请求,一般简称为XHR。

  分析简而言之网站点

  我们的目标网站是用壳网来分析。地址

  我们可以看到这个网页没有翻页按钮,当我们不断拉下请求时,网页会自动为我们加载更多内容。但是,当我们查看网页 url 时,它并没有随着页面加载请求而改变。而当我们直接请求这个url时,显然只能获取到第一页的html内容。

  

  那么我们如何获取所有页面的数据呢?

  我们在Chrome中打开开发者工具(F12)。我们点击Network,点击XHR选项卡。然后我们刷新页面并拉下请求。这时候我们可以看到XHR选项卡,每次页面加载会弹出一个请求。

  我们点击第一个请求,可以看到他的参数:

  检索类型:按主题

  限制:20

  偏移量:18

  -:86

  点击第二个请求后,参数如下:

  检索类型:按主题

  限制:20

  偏移量:38

  -:87

  limit参数是网页每页被限制加载的文章个数,offset是页数。然后往下看,我们会发现每次请求的offset参数都会增加20。

  然后我们查看每个请求的响应内容,这是一个格式化的数据。我们点击结果按钮,可以看到20条文章的数据信息。这样我们就成功找到了我们需要的信息的位置,在请求头中可以看到json数据存放的url地址。;limit=20&offset=18

  

  爬取过程开始

  我们的工具仍然使用 BeautifulSoup 解析的请求。

  首先,我们需要对Ajax请求进行分析,获取所有页面的信息。通过上面网页的分析,我们可以得到ajax加载的json数据的url地址:;limit=20&offset=18

  我们需要构造这个 URL。

  # 导入可能要用到的模块

import requests

from urllib.parse import urlencode

from requests.exceptions import ConnectionError

# 获得索引页的信息

def get_index(offset):

base_url = 'http://www.guokr.com/apis/minisite/article.json?'

data = {

'retrieve_type': "by_subject",

'limit': "20",

'offset': offset

}

params = urlencode(data)

url = base_url + params

try:

resp = requests.get(url)

if resp.status_code == 200:

return resp.text

return None

except ConnectionError:

print('Error.')

return None

  我们将从上面分析页面得到的请求参数构造成字典数据,然后我们可以手动构造url,但是urllib库已经为我们提供了编码方式,我们可以直接使用它来构造完整的url。然后是请求页面内容的标准请求。

  import json

# 解析json,获得文章url

def parse_json(text):

try:

result = json.loads(text)

if result:

for i in result.get('result'):

# print(i.get('url'))

yield i.get('url')

except:

pass

  我们使用 josn.loads 方法解析 json 并将其转换为 json 对象。然后直接通过字典的操作,得到文章的url地址。这里使用yield为每个请求返回一个url,以减少内存消耗。由于后面爬的时候会弹出一个json解析错误,这里直接过滤就好了。

  这里我们可以尝试打印看看是否运行成功。

  既然获取了文章的url,那么获取文章的数据就很简单了。此处不作详细说明。目标是获取 文章 的标题、作者和内容。

  由于有的文章收录了一些图片,所以我们可以过滤掉文章内容中的图片。

  from bs4 import BeautifulSoup

# 解析文章页

def parse_page(text):

try:

soup = BeautifulSoup(text, 'lxml')

content = soup.find('div', class_="content")

title = content.find('h1', id="articleTitle").get_text()

author = content.find('div', class_="content-th-info").find('a').get_text()

article_content = content.find('div', class_="document").find_all('p')

all_p = [i.get_text() for i in article_content if not i.find('img') and not i.find('a')]

article = '\n'.join(all_p)

# print(title,'\n',author,'\n',article)

data = {

'title': title,

'author': author,

'article': article

}

return data

except:

pass

  这里,在进行多进程爬取的时候,BeautifulSoup也会报错,还是直接过滤。我们将得到的数据以字典的形式保存,方便保存数据库。

  下一步是保存数据库的操作。这里我们使用MongoDB进行数据存储。具体方法在上一篇文章文章中有​​提到。关于他的细节就不赘述了。

  import pymongo

from config import *

client = pymongo.MongoClient(MONGO_URL, 27017)

db = client[MONGO_DB]

def save_database(data):

if db[MONGO_TABLE].insert(data):

print('Save to Database successful', data)

return True

return False

  我们将数据库名和表名保存在config配置文件中,并将配置信息导入到文件中,这样会方便代码的管理。

  最后,由于诺虎网的数据还是很多的,如果我们想抓取很多数据,可以使用多进程。

  from multiprocessing import Pool

# 定义一个主函数

def main(offset):

text = get_index(offset)

all_url = parse_json(text)

for url in all_url:

resp = get_page(url)

data = parse_page(resp)

if data:

save_database(data)

if __name__ == '__main__':

pool = Pool()

offsets = ([0] + [i*20+18 for i in range(500)])

pool.map(main, offsets)

pool.close()

pool.join()

  该函数的参数偏移量是页数。经过我的观察,国科网的最后一个页码是12758,有637页。在这里,我们抓取了 500 个页面。进程池的map方法类似于Python内置的map方法。

  

  那么对于一些使用Ajax加载的网页,我们可以这样爬取。

  项目地址

  这里

  如果觉得有帮助,请star。

  谢谢阅读

  系列文章

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线