从零开始学Python爬虫:三步实现网页数据自动采集
在当今数据驱动的时代,手动复制粘贴网页内容早已成为低效的代名词。无论你是需要监控竞品价格、搜集行业报告,还是搭建个人知识库,掌握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源码,但夹杂大量标签。下一步就是从中提取有效信息。
利用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:
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、代理池、登录态等问题,但万变不离其宗:请求→解析→存储。最后强调,爬取数据时请遵守法律法规,不得侵犯个人隐私或商业机密。遵守上述原则,爬虫将是你高效工作的利器。
