第4章:Web数据采集基础

说实话,做数据采集这些年,我踩过的坑比走过的路还多。但Web采集这块,只要你把基础打牢了,后面就顺了。今天咱们就聊聊HTTP协议、HTML基础、静态页面抓取和动态页面抓取这四块内容。

4.1 HTTP协议与请求响应模型

HTTP协议,说白了就是浏览器和服务器之间对话的规矩。你想想看,你在浏览器输入一个网址,回车,页面就出来了。这背后发生了什么?

我习惯把HTTP请求比作点外卖:

  • 客户端(浏览器):你就是那个饿了的食客
  • 服务器:后厨的厨师
  • HTTP请求:你下的单
  • HTTP响应:厨师做好的菜

一个完整的HTTP请求包含四部分:

请求行:GET /index.html HTTP/1.1
请求头:Host: www.example.com
        User-Agent: Mozilla/5.0
        Cookie: session_id=12345
空行
请求体:(GET请求没有,POST请求有数据)

响应也是类似的:

状态行:HTTP/1.1 200 OK
响应头:Content-Type: text/html
        Content-Length: 1234
空行
响应体:<html>...</html>

重点记住几个状态码:

  • 200:成功,一切正常
  • 301/302:重定向,页面搬家了
  • 403:禁止访问,你没权限
  • 404:页面不存在
  • 500:服务器内部错误

我在项目中遇到过最坑的事:爬一个电商网站,明明代码没问题,但就是拿不到数据。后来一查,原来是服务器返回了301重定向,我的代码没处理。嗯,从那以后我写爬虫第一件事就是检查状态码。

4.2 HTML/CSS基础与选择器

HTML是网页的骨架,CSS是衣服。你要抓数据,首先得知道数据长什么样。

一个典型的HTML结构:

<!DOCTYPE html>
<html>
<head>
    <title>商品列表</title>
</head>
<body>
    <div class="product">
        <h2 class="name">iPhone 15</h2>
        <span class="price">¥6999</span>
        <a href="/detail/123">查看详情</a>
    </div>
</body>
</html>

CSS选择器是定位元素的利器。我个人最常用的几种:

选择器 示例 说明
标签选择器 div 选中所有div标签
类选择器 .price 选中class="price"的元素
ID选择器 #main 选中id="main"的元素
后代选择器 div .price 选中div内部的.price元素
属性选择器 [href] 选中所有带href属性的元素

小技巧:在浏览器按F12打开开发者工具,用Elements面板可以直接右键复制CSS选择器。我刚开始学的时候全靠这个功能,省了不少事。

4.3 静态网页抓取(Requests+BeautifulSoup)

静态网页,就是内容直接写在HTML里的页面。这种最简单,用Requests拿HTML,用BeautifulSoup解析就行。

我写爬虫的标配代码:

import requests
from bs4 import BeautifulSoup

# 1. 发送请求
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
}
url = 'https://example.com/products'
response = requests.get(url, headers=headers)

# 2. 检查状态
if response.status_code == 200:
    print('请求成功!')
else:
    print(f'请求失败,状态码:{response.status_code}')

# 3. 解析HTML
soup = BeautifulSoup(response.text, 'html.parser')

# 4. 提取数据
products = soup.select('.product')
for product in products:
    name = product.select_one('.name').text.strip()
    price = product.select_one('.price').text.strip()
    print(f'{name}: {price}')

这里有几个坑,我当年都踩过:

避坑指南:

  • 一定要加User-Agent,不然很多网站直接拒绝你
  • response.encoding要设置正确,中文乱码就靠它
  • BeautifulSoup的解析器用'lxml'比'html.parser'快很多

我曾经爬一个新闻网站,数据总是少几条。排查了半天,发现是页面用了分页,我只抓了第一页。所以,记得检查页面有没有分页机制。

4.4 动态网页抓取(Selenium基础)

现在很多网站都用JavaScript动态加载数据。你直接拿Requests请求,HTML里啥都没有。这时候就得请出Selenium了。

Selenium说白了就是一个自动化浏览器工具。它能模拟真实用户的操作:点击、滚动、输入文字等等。

基本用法:

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

# 启动浏览器
driver = webdriver.Chrome()

# 访问页面
driver.get('https://example.com')

# 等待元素加载
wait = WebDriverWait(driver, 10)
element = wait.until(
    EC.presence_of_element_located((By.CLASS_NAME, 'product'))
)

# 获取数据
products = driver.find_elements(By.CLASS_NAME, 'product')
for product in products:
    name = product.find_element(By.CLASS_NAME, 'name').text
    print(name)

# 关闭浏览器
driver.quit()

什么时候用Selenium?

  • 页面内容是通过AJAX异步加载的
  • 需要模拟用户操作(点击、滚动、翻页)
  • 页面有复杂的JavaScript渲染
  • 需要处理登录、验证码等交互

但Selenium也有缺点:慢、吃内存。我建议能用Requests解决的,就别用Selenium。杀鸡不用牛刀嘛。

最后,我画了一张图,把今天讲的内容串起来:

Web数据采集核心流程 1. 分析页面 2. 判断页面类型 静态 vs 动态 静态:Requests 动态:Selenium 3. 解析数据 BeautifulSoup find_elements 4. 存储数据 CSV Excel 数据库 JSON 核心原则:先分析,再动手;静态优先,动态兜底

这张图把整个流程串起来了。你想想看,从分析页面开始,判断是静态还是动态,然后选择对应的工具去抓取,最后把数据存起来。每一步都有对应的技术选型。

好了,这一章的内容就到这。记住一句话:Web采集没有银弹,理解原理比背代码更重要。遇到问题多想想HTTP协议,多看看HTML结构,很多问题自然就解决了。


公众号:蓝海资料掘金营,微信deep3321