随着Web技术不断发展,越来越多网站采用了AJAX、动态渲染等技术来加载数据。以今日头条(https://www.toutiao.com)为例,用户打开网页时并不会一次性加载所有信息,而是通过JavaScript触发异步请求分批加载新闻数据。
对于传统爬虫,这种动态加载的数据变得“隐形”:
于是,如何精准嗅探出这些AJAX请求路径、参数及触发方式,成了采集中的新难题。
设定任务:从 https://www.toutiao.com 中搜索关键词“AI”,采集相关新闻的标题、简介、作者和发布时间。初看HTML源代码,会发现结构复杂、数据嵌入 JavaScript 中,无法直接提取。
我们尝试用传统 BeautifulSoup + requests 抓取,发现返回结果中并无新闻数据,失败告终。
面对这种问题,我们尝试以下三种方法:
因此,我们需要一种更智能的方式:让爬虫“学会”识别页面中的AJAX行为并自动推测请求方式。
借助机器学习+页面行为特征提取,我们构建了一个智能嗅探器,流程如下:
以下是核心代码实现部分:
import requests
import json
import time
import random
from urllib.parse import quote
# 爬虫代理IP配置(以亿牛云代理为例)
proxy_host = "proxy.16yun.cn" #your-proxy-domain
proxy_port = "31000" #your-port
proxy_user = "16YUN" #your-username
proxy_pass = "16IP" #your-password
# 构造代理格式
proxies = {
"http": f"http://{proxy_user}:{proxy_pass}@{proxy_host}:{proxy_port}",
"https": f"http://{proxy_user}:{proxy_pass}@{proxy_host}:{proxy_port}"
}
# 设置User-Agent和cookie,模拟真实用户访问
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36",
"cookie": "tt_webid=1234567890abcdef; other_cookies=xxx"
}
# 关键词搜索
keyword = "AI"
encoded_keyword = quote(keyword)
# 模拟 AJAX 请求接口(来自浏览器F12提取的接口,带关键词参数)
def fetch_news(keyword):
url = f"https://www.toutiao.com/api/search/content/?aid=24&app_name=web_search&offset=0&format=json&keyword={encoded_keyword}&autoload=true&count=20&en_qc=1&cur_tab=1&from=search_tab"
try:
response = requests.get(url, headers=headers, proxies=proxies, timeout=10)
data = response.json()
result = []
for item in data.get("data", []):
if not item.get("title"):
continue
news = {
"标题": item.get("title", ""),
"简介": item.get("abstract", ""),
"作者": item.get("media_name", "未知"),
"时间": item.get("datetime", "未知")
}
result.append(news)
return result
except Exception as e:
print(f"抓取出错:{e}")
return []
# 分类存储(按作者存为独立文件)
def save_by_author(news_list):
from collections import defaultdict
import os
grouped = defaultdict(list)
for news in news_list:
grouped[news["作者"]].append(news)
if not os.path.exists("output"):
os.mkdir("output")
for author, items in grouped.items():
filename = f"output/{author}.json"
with open(filename, "w", encoding="utf-8") as f:
json.dump(items, f, ensure_ascii=False, indent=2)
if __name__ == "__main__":
news_data = fetch_news(keyword)
print(f"共抓取到 {len(news_data)} 条资讯")
save_by_author(news_data)
这类动态接口的一个关键特征是:参数格式、接口路径在用户行为驱动下形成。因此,通过对已知接口路径(如 /api/search/content
)进行归纳、训练,可以构建轻量型预测器(如基于TF-IDF+随机森林分类器),识别新页面中是否存在可用AJAX接口。
当然,本文采用了简化版“人工辅助+规则模板”识别方式。在实际大型项目中,可以扩展为:
面对复杂的前端动态渲染,靠写死的路径早已无法应对日益频繁的页面结构变动。通过引入机器学习和行为识别,我们能让爬虫具备“嗅觉”和“判断力”,甚至主动适应页面的变化。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。