引言
在爬虫技术应用中,新闻数据的抓取一直是一个常见的场景,尤其是对于新闻网站的关键词搜索结果进行抓取,已成为舆情监控、数据分析和信息挖掘等领域的基础任务。百度新闻作为中国最大的搜索引擎之一,其庞大的新闻数据资源吸引了大量开发者进行爬取与分析。
本文将带你通过一个实战案例,教你如何使用 Python 和 BeautifulSoup 来构建一个 异步分页爬虫,抓取 百度新闻 上某一关键词搜索结果的最新 500 条标题与链接。在爬虫中,我们将重点介绍 分页解析 和 请求头伪装 技巧,避免反爬机制的干扰。
通过这个案例,你不仅能学会如何实现高效的数据抓取,还能深入理解异步爬虫、请求伪装、反爬技术等核心概念。
1. 项目背景
百度新闻提供了多种新闻内容,用户可以通过关键词搜索来获取相关的新闻信息。而对于一些数据分析任务,批量获取这些新闻标题和链接成为了不可或缺的一步。通过爬虫抓取并存储这些数据,可以为舆情分析、热点新闻识别、自动化监控等提供宝贵的信息。
1.1 本文目标
本篇文章的目标是通过 Python 和 BeautifulSoup 来实现以下功能:
关键词搜索:抓取百度新闻搜索某个关键词的新闻结果。
分页解析:通过翻页机制,抓取多个页面的新闻数据。
异步请求:通过 aiohttp 实现异步请求,加速数据抓取。
请求头伪装:通过伪装请求头,绕过反爬虫机制,避免 IP 被封禁。
1.2 技术栈
Python 3.x
BeautifulSoup:用于 HTML 页面解析和数据提取。
aiohttp:用于异步请求。
requests:用于模拟浏览器发送请求。
asyncio:Python 的异步编程框架。
2. 爬虫设计思路
2.1 目标网页结构分析
百度新闻的搜索页面是通过动态加载内容的,因此我们需要通过分析页面的 HTML 结构来获取新闻的标题和链接。每一页的搜索结果都包含新闻的标题、链接、时间等信息。分页部分的 URL 结构较为简单,通常只需要修改页码参数即可获取下一页的内容。
2.2 异步爬虫
使用异步爬虫的好处是可以在等待服务器响应的同时执行其他任务,从而显著提高抓取速度。这里我们使用 aiohttp 和 asyncio 来实现异步请求,避免同步爬虫的性能瓶颈。
2.3 请求头伪装
为了避免被百度新闻的反爬虫机制封禁,我们需要在请求中加入伪造的 User-Agent,并设置适当的请求头,模拟正常的浏览器访问。
3. 爬虫实现
3.1 安装依赖
首先,我们需要安装相关的 Python 库。可以通过以下命令安装所需的依赖:
pip install aiohttp beautifulsoup4 requests
3.2 编写爬虫代码
以下是爬虫的完整代码实现:
import asyncio
import aiohttp
from bs4 import BeautifulSoup
import random
import requests
# 设置请求头伪装
USER_AGENTS = [
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36 Edg/91.0.864.70',
'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:91.0) Gecko/20100101 Firefox/91.0'
]
# 模拟浏览器请求头
def get_headers():
headers = {
'User-Agent': random.choice(USER_AGENTS),
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
'Accept-Encoding': 'gzip, deflate, br',
'Connection': 'keep-alive',
}
return headers
# 获取单个页面的新闻标题与链接
async def fetch_page(session, url):
headers = get_headers()
async with session.get(url, headers=headers) as response:
html = await response.text()
soup = BeautifulSoup(html, 'html.parser')
# 找到每一篇新闻的标题与链接
articles = soup.find_all('a', {
'target': '_blank'})
results = []
for article in articles:
title = article.get_text()
link = article.get('href')
if link and 'news' in link: # 过滤无效链接
results.append({
'title': title, 'link': link})
return results
# 异步抓取多个页面
async def fetch_all_pages(keyword, page_count=10):
base_url = f'https://news.baidu.com/ns?word={
keyword}&pn='
async with aiohttp.ClientSession() as session:
tasks = []
for page_num in range(page_count):
url = base_url + str(page_num * 10) # 每页10条新闻
tasks.append(fetch_page(session, url))
# 获取所有页面的结果
results = await asyncio.gather(*tasks)
return [item for sublist in results for item in sublist] # 合并结果
# 主程序
async def main(keyword, page_count=10):
news = await fetch_all_pages(keyword, page_count)
for idx, item in enumerate(news):
print(f"{
idx+1}. {
item['title']} - {
item['link']}")
# 执行爬虫
if __name__ == '__main__':
keyword = '人工智能' # 你想要搜索的关键词
asyncio.run(main(keyword, 5)) # 抓取前 5 页的新闻
3.3 代码解析
请求头伪装:
我们通过 get_headers() 函数随机选择一个 User-Agent,模拟浏览器的请求头。通过设置 Accept-Encoding 和 Connection 等字段,进一步逼近真实浏览器的请求。
异步请求:
使用 aiohttp 和 asyncio 来并发请求多个页面。每一个页面的 URL 都是基于 base_url 和不同的 pn 参数(即页码)生成的。
BeautifulSoup 解析:
每个页面返回的 HTML 被传递给 BeautifulSoup 进行解析。我们通过 soup.find_all() 获取每个新闻的标题和链接。
分页抓取:
由于百度新闻的分页是通过 URL 中的 pn 参数控制的,我们通过 page_num 来循环抓取多页的内容。
合并数据:
使用 asyncio.gather() 来并发抓取所有页面,并将每个页面的抓取结果合并成一个大的列表。
3.4 运行结果
运行爬虫后,你会看到类似如下输出:
1. 人工智能:让生活更智能 - http://news.baidu.com/ns?word=人工智能&pn=0
2. 2021 年 AI 大会总结 - http://news.baidu.com/ns?word=人工智能&pn=10
3. 人工智能赋能企业创新 - http://news.baidu.com/ns?word=人工智能&pn=20
...
4. 优化与防止封禁
4.1 控制请求频率
为了防止因请求过于频繁而导致 IP 被封禁,可以通过调整请求间隔来避免这个问题。可以设置随机的间隔时间(如每次请求之间延时 1-3 秒)。
4.2 IP 代理池
如果需要长时间抓取,可以考虑使用 代理池 来切换 IP,从而规避 IP 被封禁的风险。
5. 总结
通过本文的示例,你学会了如何构建一个高效的 百度新闻关键词搜索 爬虫,掌握了 异步请求、分页解析 和 请求头伪装 等核心技术。借助这些技术,我们可以高效地抓取百度新闻的标题与链接,应用于舆情监控、信息抽取等多个场景。
希望这篇文章能够帮助你理解并掌握现代爬虫技术,让你能够快速上手开发自己的数据采集工具。





![[2021-4-6 更新]C启动-一款快速启动、桌面美化、桌面管理工具软件 - 宋马](https://pic.songma.com/blogimg/20250422/bc94d939c6e84346b26aa50582cba1cc.jpg)










暂无评论内容