从零开始学Python爬虫:三步实现网页数据自动采集

在当今数据驱动的时代,手动复制粘贴网页内容早已成为低效的代名词。无论你是需要监控竞品价格、搜集行业报告,还是搭建个人知识库,掌握Python爬虫都能让你从重复劳动中解放出来。本文将用最直白的方式,带你从零搭建一个基础但完整的爬虫流程,全程无需高级框架,仅靠标准库和两个核心第三方库即可运行。 准备工作:安装环境与依赖库 开始前,请确保已安装Python 3.7+版本。在终端执行以下命令安装所需库:

在当今数据驱动的时代,手动复制粘贴网页内容早已成为低效的代名词。无论你是需要监控竞品价格、搜集行业报告,还是搭建个人知识库,掌握Python爬虫都能让你从重复劳动中解放出来。本文将用最直白的方式,带你从零搭建一个基础但完整的爬虫流程,全程无需高级框架,仅靠标准库和两个核心第三方库即可运行。

准备工作:安装环境与依赖库

开始前,请确保已安装Python 3.7+版本。在终端执行以下命令安装所需库:

pip install requests beautifulsoup4 lxml

Requests负责发送HTTP请求,BeautifulSoup负责解析HTML结构,lxml作为解析器能大幅提升速度。如果你使用Anaconda,这些库通常已预装。

第一步:发送请求并获取响应内容

爬虫的核心是模拟浏览器向服务器发送请求。我们以某公开新闻网站为例,抓取首页文章标题。首先导入库并设置请求头,避免部分网站拒绝陌生用户代理:

import requests
from bs4 import BeautifulSoup

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'
}
url = 'https://example-news.com'
response = requests.get(url, headers=headers, timeout=10)
print(response.status_code)  # 200表示成功

若返回200,说明连接正常。此时response.text保留了网页的全部HTML源码,但夹杂大量标签。下一步就是从中提取有效信息。

第二步:解析HTML并定位目标数据

利用BeautifulSoup的select方法,通过CSS选择器精准锁定目标元素。假设我们知道文章标题都在<h2 class="article-title">中:

soup = BeautifulSoup(response.text, 'lxml')
titles = soup.select('h2.article-title')
for title in titles[:5]:
    print(title.get_text(strip=True))

strip=True能去除文字首尾空格。如果你不确定选择器怎么写,可以使用浏览器开发者工具(F12)点击元素,右键复制“Selector”即可。

第三步:处理分页与循环抓取

单页数据往往不够,我们需要遍历多个页面。观察网页URL规律,通常为/page/2/这类结构。写一个循环来批量抓取:

for page_num in range(1, 6):  # 抓取前5页
    page_url = f'https://example-news.com/page/{page_num}'
    res = requests.get(page_url, headers=headers, timeout=10)
    soup = BeautifulSoup(res.text, 'lxml')
    # 复用相同的选择器
    for title in soup.select('h2.article-title'):
        print(f'第{page_num}页:', title.get_text(strip=True))

务必在循环中加入time.sleep(1)每秒暂停,既模拟人类操作,又避免给服务器造成压力。如果被网站封禁IP,可以尝试更换代理或增加延迟。

进阶技巧:处理动态加载与编码问题

很多现代网站通过JavaScript动态填充内容,直接requests抓不到数据。此时可先检查网络请求中的XHR接口,或使用开发者工具手动模拟API请求。若网页源码乱码,可能是编码不匹配,可在response后加一行:

response.encoding = response.apparent_encoding
规范与安全:尊重robots协议

在编写爬虫前,务必查看目标网站的robots.txt(如https://example-news.com/robots.txt),它明确列出允许或禁止抓取的路径。此外,控制抓取频率,切勿在短时间内发起大量请求,否则可能违反网站服务条款。

整合代码:一个完整的最小示例

将上述步骤合并,形成一个可复用的脚本框架:

import requests
from bs4 import BeautifulSoup
import time

def fetch_titles(base_url, start_page, end_page):
    all_titles = []
    headers = {'User-Agent': 'Mozilla/5.0'}
    for p in range(start_page, end_page+1):
        url = f'{base_url}/page/{p}'
        try:
            r = requests.get(url, headers=headers, timeout=5)
            r.encoding = r.apparent_encoding
            soup = BeautifulSoup(r.text, 'lxml')
            all_titles.extend([t.get_text(strip=True) for t in soup.select('h2.article-title')])
            time.sleep(1.2)
        except Exception as e:
            print(f'第{p}页出错: {e}')
    return all_titles

if __name__ == '__main__':
    result = fetch_titles('https://example-news.com', 1, 3)
    for i, title in enumerate(result, 1):
        print(f'{i}. {title}')
调试与异常处理

网络环境不稳定时,建议使用try-except捕获超时或连接错误。还可以添加重试机制:设置session = requests.Session()复用连接,提升效率。如果遇到验证码,说明触发了反爬机制,考虑使用Selenium或降低访问频率。

数据持久化:保存到CSV文件

获取数据后,简单打印难以满足实际需求。以下代码将标题保存至本地CSV:

import csv
with open('titles.csv', 'w', newline='', encoding='utf-8') as f:
    writer = csv.writer(f)
    writer.writerow(['序号', '标题'])
    for idx, title in enumerate(result, 1):
        writer.writerow([idx, title])
结语与非技术提醒

学习爬虫的关键在于“按需取材”——先手动在浏览器复制选择器,再编写循环逻辑。本文案例适用于无登录、无严格反爬的公开网站。实际项目中,你可能需要处理Cookie、代理池、登录态等问题,但万变不离其宗:请求→解析→存储。最后强调,爬取数据时请遵守法律法规,不得侵犯个人隐私或商业机密。遵守上述原则,爬虫将是你高效工作的利器。

免责声明:本文内容来源于公开资料、用户提交或站内整理,仅供学习与参考,不构成任何投资、医疗、法律或专业建议。请结合实际情况自行判断,相关风险由使用者自行承担。