网络爬虫基础:从HTTP到数据提取
做舆情分析,第一步就是拿到数据。怎么拿?说白了,就是模拟人去访问网页的过程。我刚开始接触爬虫时,以为它多神秘,后来发现核心就三件事:发请求、收响应、提取信息。今天咱们就把这三件事拆开揉碎了讲清楚。
本章知识体系:HTTP协议 → Requests库 → BeautifulSoup解析 → XPath/CSS选择器
HTTP协议:爬虫的交通规则
HTTP协议,说白了就是浏览器和服务器之间沟通的「暗号」。你想想看,你在地址栏敲个网址,回车,背后发生了什么?
我习惯把HTTP请求想象成你去餐厅点菜:
- 请求行:相当于你说「服务员,我要一份宫保鸡丁」—— 这就是GET请求
- 请求头:相当于你补充「少放辣,多放花生」—— 这是附加信息
- 请求体:如果你要提交表单,就像你填了个菜单递给服务员—— 这是POST请求
服务器收到后,会返回一个响应。响应里有个东西特别重要——状态码。我在项目中遇到过无数次,爬虫跑着跑着突然报错,一看状态码:
| 状态码 | 含义 | 常见场景 |
|---|---|---|
| 200 | 请求成功 | 正常返回数据 |
| 301/302 | 重定向 | 网址变了,自动跳转 |
| 403 | 禁止访问 | 被反爬了,需要加请求头 |
| 404 | 页面不存在 | 链接失效或写错了 |
| 500 | 服务器内部错误 | 对方服务器崩了,过会儿再试 |
避坑提醒:我曾经遇到过一个舆情网站,明明页面能打开,但爬虫就是拿不到数据。查了半天,发现是缺少 User-Agent 请求头。服务器一看「咦,没有浏览器标识,肯定是爬虫」,直接返回403。加个常见的浏览器UA就解决了。
Requests库:Python里的HTTP利器
Python里发HTTP请求,我个人最常用的是 requests 库。为啥?因为它太直观了。你看:
import requests
# GET请求 - 获取网页
url = "https://example.com/news"
response = requests.get(url)
print(response.text) # 打印HTML内容
# POST请求 - 提交数据
data = {"keyword": "舆情", "page": 1}
response = requests.post(url, data=data)
print(response.json()) # 如果返回JSON
嗯,这里要注意几个细节:
response.text返回的是字符串格式的HTMLresponse.content返回的是字节流,适合下载图片response.status_code可以检查状态码
我建议你养成一个习惯:每次发请求前,先伪造一下请求头。很多网站对爬虫不友好,但加个 headers 参数就能伪装成正常浏览器:
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
"Referer": "https://www.baidu.com/"
}
response = requests.get(url, headers=headers)
小技巧:如果你需要保持登录状态(比如爬取需要登录的舆情平台),用 requests.Session()。它会自动帮你管理Cookie,就像浏览器一样记住你是谁。
BeautifulSoup:HTML的「解剖刀」
拿到HTML源码后,怎么提取我们需要的信息?BeautifulSoup 就是干这个的。它能把杂乱的HTML变成一棵结构清晰的树,然后我们在这棵树上「摘果子」。
安装很简单:pip install beautifulsoup4
基本用法:
from bs4 import BeautifulSoup
html = "<html><body><h1>舆情标题</h1><p class='content'>正文内容</p></body></html>"
soup = BeautifulSoup(html, 'html.parser')
# 提取标题
title = soup.find('h1').text
print(title) # 输出:舆情标题
# 提取正文
content = soup.find('p', class_='content').text
print(content) # 输出:正文内容
我在项目中遇到过最头疼的情况是——网页结构不规范。有的标签没闭合,有的属性值带空格。BeautifulSoup 的 html.parser 解析器比较宽容,但遇到复杂的页面,我建议换成 lxml 解析器,速度更快,容错性也更好。
常用的查找方法:
find():找第一个匹配的元素find_all():找所有匹配的元素,返回列表select():用CSS选择器查找,后面会讲
实战经验:舆情数据通常藏在 <div> 或 <span> 标签里。我一般先打印出 soup.prettify(),看看HTML结构长什么样,再决定用什么选择器。别一上来就写代码,先观察,再动手。
XPath与CSS选择器:精准定位的艺术
BeautifulSoup 的 find() 方法虽然好用,但遇到深层嵌套的HTML,写起来就有点啰嗦了。这时候,XPath 和 CSS 选择器就派上用场了。
XPath:用路径说话
XPath 就像文件路径一样,从根节点一步步定位到目标元素。我刚开始学的时候觉得它语法怪,用多了才发现真香。
from lxml import html
tree = html.fromstring(response.content)
# 绝对路径:从根开始
title = tree.xpath('/html/body/div[1]/h1/text()')
# 相对路径:用 // 跳过中间层级
titles = tree.xpath('//h1/text()')
# 按属性筛选
items = tree.xpath('//div[@class="news-item"]/text()')
# 按文本内容筛选
result = tree.xpath('//p[contains(text(), "舆情")]/text()')
常用的XPath表达式:
| 表达式 | 含义 |
|---|---|
/ |
从根节点选取 |
// |
从任意位置选取 |
. |
当前节点 |
.. |
父节点 |
@ |
选取属性,如 @class |
text() |
选取文本内容 |
曾经踩过的坑:XPath 的索引是从1开始的,不是0!我第一次用 //div[1] 想取第一个div,结果取到了第二个。查了半天文档才发现这个「坑」。记住了,XPath里 [1] 就是第一个,不是第零个。
CSS选择器:前端工程师的最爱
如果你写过CSS,那CSS选择器对你来说就是老朋友了。BeautifulSoup 的 select() 方法直接支持CSS选择器:
# 标签选择器
soup.select('h1')
# 类选择器
soup.select('.news-title')
# ID选择器
soup.select('#main-content')
# 属性选择器
soup.select('a[href]') # 所有带href属性的a标签
soup.select('a[href*="weibo"]') # href包含"weibo"的a标签
# 组合选择器
soup.select('div.news-item > h2') # 直接子元素
soup.select('div p') # 后代元素
我个人习惯:简单的页面用CSS选择器,因为写起来快;复杂的页面用XPath,因为表达能力更强。你想想看,CSS选择器能做的,XPath基本都能做,但反过来不一定。
调试小技巧:在浏览器里按F12打开开发者工具,选中目标元素,右键 → Copy → Copy XPath 或 Copy selector。直接粘贴到代码里,省时省力。但注意,浏览器生成的XPath有时过于冗长,我会手动精简一下。
实战组合:一个完整的舆情数据抓取流程
把今天学的串起来,写一个完整的例子:
import requests
from bs4 import BeautifulSoup
# 1. 发请求
headers = {"User-Agent": "Mozilla/5.0"}
url = "https://example.com/yuqing"
resp = requests.get(url, headers=headers)
# 2. 检查状态
if resp.status_code == 200:
# 3. 解析HTML
soup = BeautifulSoup(resp.text, 'lxml')
# 4. 提取数据
articles = soup.select('div.article-item')
for art in articles:
title = art.find('h2').text.strip()
summary = art.find('p', class_='summary').text.strip()
print(f"标题:{title}\n摘要:{summary}\n---")
else:
print(f"请求失败,状态码:{resp.status_code}")
这个流程,说白了就是爬虫的「三板斧」。我在做舆情监控系统时,每天就是用这个模式,定时抓取几十个网站的数据。稳定运行了大半年,没出过问题。
好了,HTTP协议、Requests库、BeautifulSoup、XPath和CSS选择器,这些就是爬虫的「基本功」。练熟了,后面学Scrapy框架、动态页面抓取,都会轻松很多。
公众号:蓝海资料掘金营,微信deep3321