百度新闻关键词搜索爬虫实战:异步分页抓取500条最新标题与链接(附源码与请求头伪装技巧)

引言

在爬虫技术应用中,新闻数据的抓取一直是一个常见的场景,尤其是对于新闻网站的关键词搜索结果进行抓取,已成为舆情监控、数据分析和信息挖掘等领域的基础任务。百度新闻作为中国最大的搜索引擎之一,其庞大的新闻数据资源吸引了大量开发者进行爬取与分析。

本文将带你通过一个实战案例,教你如何使用 PythonBeautifulSoup 来构建一个 异步分页爬虫,抓取 百度新闻 上某一关键词搜索结果的最新 500 条标题与链接。在爬虫中,我们将重点介绍 分页解析请求头伪装 技巧,避免反爬机制的干扰。

通过这个案例,你不仅能学会如何实现高效的数据抓取,还能深入理解异步爬虫、请求伪装、反爬技术等核心概念。

1. 项目背景

百度新闻提供了多种新闻内容,用户可以通过关键词搜索来获取相关的新闻信息。而对于一些数据分析任务,批量获取这些新闻标题和链接成为了不可或缺的一步。通过爬虫抓取并存储这些数据,可以为舆情分析、热点新闻识别、自动化监控等提供宝贵的信息。

1.1 本文目标

本篇文章的目标是通过 PythonBeautifulSoup 来实现以下功能:

关键词搜索:抓取百度新闻搜索某个关键词的新闻结果。
分页解析:通过翻页机制,抓取多个页面的新闻数据。
异步请求:通过 aiohttp 实现异步请求,加速数据抓取。
请求头伪装:通过伪装请求头,绕过反爬虫机制,避免 IP 被封禁。

1.2 技术栈

Python 3.x
BeautifulSoup:用于 HTML 页面解析和数据提取。
aiohttp:用于异步请求。
requests:用于模拟浏览器发送请求。
asyncio:Python 的异步编程框架。

2. 爬虫设计思路

2.1 目标网页结构分析

百度新闻的搜索页面是通过动态加载内容的,因此我们需要通过分析页面的 HTML 结构来获取新闻的标题和链接。每一页的搜索结果都包含新闻的标题、链接、时间等信息。分页部分的 URL 结构较为简单,通常只需要修改页码参数即可获取下一页的内容。

2.2 异步爬虫

使用异步爬虫的好处是可以在等待服务器响应的同时执行其他任务,从而显著提高抓取速度。这里我们使用 aiohttpasyncio 来实现异步请求,避免同步爬虫的性能瓶颈。

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-EncodingConnection 等字段,进一步逼近真实浏览器的请求。

异步请求
使用 aiohttpasyncio 来并发请求多个页面。每一个页面的 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. 总结

通过本文的示例,你学会了如何构建一个高效的 百度新闻关键词搜索 爬虫,掌握了 异步请求分页解析请求头伪装 等核心技术。借助这些技术,我们可以高效地抓取百度新闻的标题与链接,应用于舆情监控、信息抽取等多个场景。

希望这篇文章能够帮助你理解并掌握现代爬虫技术,让你能够快速上手开发自己的数据采集工具。

© 版权声明
THE END
如果内容对您有所帮助,就支持一下吧!
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容