如何使用 Scrapy 爬取动态生成的 Ajax 数据?
- 确认 Ajax 请求的 URL 和参数
首先需要确定所爬取的页面中使用了哪些 Ajax 请求,并查看这些请求的 URL 和参数。可以使用浏览器的开发者工具(例如 Chrome 的开发者工具)来查看网络请求。
以“pidancode.com”网站为例,该网站有一个文章列表,每次滚动页面到底部都会加载更多的文章。这个操作就是通过 Ajax 请求实现的。使用 Chrome 的开发者工具,可以查看到该请求的 URL 为“https://www.pidancode.com/wp-admin/admin-ajax.php?order=bytime&paged=2&post_type=post&action=zibll_load_postlist”(其中 paged 参数表示请求的页数)。
- 通过 Scrapy 发起 Ajax 请求
在 Scrapy 中,使用 scrapy.Request 类可以发起网络请求。在发起 Ajax 请求时,需要设置以下参数。
- url:请求的 URL
- method:请求的方法(通常为 POST 或 GET)
- headers:请求头信息
- body:请求体(如果是 POST 请求)
以“pidancode.com”网站为例,发起一个 Ajax 请求的代码如下。
import scrapy class AjaxSpider(scrapy.Spider): name = "ajax" start_urls = ["https://www.pidancode.com"] def parse(self, response): # 构建请求头信息 headers = { "Accept": "application/json, text/javascript, */*; q=0.01", "Accept-Encoding": "gzip, deflate, br", "Accept-Language": "zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7", "Connection": "keep-alive", "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8", "Referer": "https://www.pidancode.com/", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.63 Safari/537.36", "X-Requested-With": "XMLHttpRequest" } # 构建请求体 body = {"action": "zibll_load_postlist", "paged": "2", "order": "bytime", "list_only": "1"} # 发起 Ajax 请求 yield scrapy.Request( url="https://www.pidancode.com/wp-admin/admin-ajax.php", method="POST", headers=headers, body=urllib.parse.urlencode(body), callback=self.parse_ajax_response ) def parse_ajax_response(self, response): # 解析响应数据 data = json.loads(response.body) for post in data: # 提取文章标题和链接 title = post["post_title"] url = post["permalink"] # 处理提取到的数据 ...
代码中,首先构建了请求头信息和请求体。注意,在请求头中添加了“X-Requested-With: XMLHttpRequest”的信息,这是 Ajax 请求的标志之一。接着使用 scrapy.Request 发起 Ajax 请求,并指定了回调函数。
-
解析 Ajax 响应
得到 Ajax 响应后,可以使用回调函数来解析响应中的数据。例如,“pidancode.com”网站的 Ajax 响应返回的就是一个 JSON 格式的数据。可以使用 Python 的 json 模块将其解析为字典或列表,然后提取需要的数据进行处理。 -
完整的 Scrapy 代码示例
import scrapy import json import urllib.parse class AjaxSpider(scrapy.Spider): name = "ajax" start_urls = ["https://www.pidancode.com"] def parse(self, response): # 构建请求头信息 headers = { "Accept": "application/json, text/javascript, */*; q=0.01", "Accept-Encoding": "gzip, deflate, br", "Accept-Language": "zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7", "Connection": "keep-alive", "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8", "Referer": "https://www.pidancode.com/", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.63 Safari/537.36", "X-Requested-With": "XMLHttpRequest" } # 构建请求体 body = {"action": "zibll_load_postlist", "paged": "2", "order": "bytime", "list_only": "1"} # 发起 Ajax 请求 yield scrapy.Request( url="https://www.pidancode.com/wp-admin/admin-ajax.php", method="POST", headers=headers, body=urllib.parse.urlencode(body), callback=self.parse_ajax_response ) def parse_ajax_response(self, response): # 解析响应数据 data = json.loads(response.body) for post in data: # 提取文章标题和链接 title = post["post_title"] url = post["permalink"] # 处理提取到的数据 ...
相关文章