深度学习——Python 爬虫原理与实战:从入门到项目实践

一、引言

在信息爆炸的时代,数据是最宝贵的资源。无论是科研分析、市场调查、AI模型训练,还是舆情监控,都离不开大量的数据支撑。然而,很多数据并不会直接开放下载,而是存在于各种网页、API或动态交互界面中。

于是,"网络爬虫(Web Crawler)"便应运而生------它是一种自动化程序,用于在互联网上采集目标数据,是数据科学与人工智能领域的"基础设施"。

本文将系统介绍爬虫的原理、类型、关键技术、反爬机制以及实战案例,帮助读者从理论到实操全面掌握这一强大技术。


二、爬虫的基本原理

1. 什么是网络爬虫

网络爬虫是一种自动访问网页并提取数据的程序。本质上,它模拟了人类打开浏览器、点击网页、复制内容的行为,只不过速度更快、规模更大。

典型的爬虫流程如下:

  1. 发送请求(Request):程序向目标网站服务器发送HTTP请求。
  2. 获取响应(Response):服务器返回网页内容(HTML、JSON、XML等)。
  3. 解析数据(Parse):使用正则表达式、XPath、BeautifulSoup等工具提取所需内容。
  4. 存储数据(Save):将数据保存为CSV、数据库或JSON文件。

例如,访问 https://quotes.toscrape.com 时,浏览器实际上发送了一条HTTP请求,服务器返回HTML文本;我们只需模拟这个过程即可实现自动采集。


2. HTTP 协议与请求头解析

要理解爬虫,首先要掌握 HTTP(超文本传输协议)。每当我们打开网页时,都会进行一次客户端与服务器之间的通信:

  • GET 请求:获取资源(最常见)
  • POST 请求:提交数据(如登录、搜索)
  • PUT/DELETE:修改或删除资源
  • Headers:包含浏览器类型、Cookie、Referer 等信息
  • Body:请求或响应的主体内容(HTML/JSON)

一个最简单的HTTP请求示例如下:

复制代码
import requests

url = "https://quotes.toscrape.com"
response = requests.get(url)
print(response.status_code)  # 查看状态码
print(response.text)         # 输出网页内容

输出的 response.text 就是整个网页的HTML源码。


3. HTML结构与数据解析

网页的结构是层级化的HTML树。

比如下面是一段HTML:

复制代码
<div class="quote">
  <span class="text">"The world as we have created it..."</span>
  <small class="author">Albert Einstein</small>
</div>

我们可以使用 BeautifulSoup 解析其中的数据:

复制代码
from bs4 import BeautifulSoup

html = response.text
soup = BeautifulSoup(html, 'html.parser')

for quote in soup.find_all('div', class_='quote'):
    text = quote.find('span', class_='text').get_text()
    author = quote.find('small', class_='author').get_text()
    print(text, '-', author)

运行结果:

复制代码
"The world as we have created it..." - Albert Einstein
"It is our choices..." - J.K. Rowling
...

这就是一个最简单的爬虫雏形:

请求网页 → 解析内容 → 输出结果。


三、爬虫案例:爬取名言网站 QuotesToScrape

这是一个专门为学习爬虫设计的网站(不会封IP)。

1. 项目目标

爬取网站中所有的名人名言及作者,并保存到CSV文件中。

2. 主要步骤

(1) 分析网页结构

打开浏览器开发者工具(F12 → Elements),可以看到每条名言都在:

复制代码
<div class="quote">
  <span class="text">"..."</span>
  <small class="author">...</small>
  <a href="/author/Albert-Einstein">More</a>
</div>

并且底部有分页链接:

复制代码
<li class="next"><a href="/page/2/">Next</a></li>
(2) 代码实现
复制代码
import requests
from bs4 import BeautifulSoup
import csv

base_url = "https://quotes.toscrape.com"
url = "/page/1/"
all_quotes = []

while url:
    res = requests.get(base_url + url)
    soup = BeautifulSoup(res.text, "html.parser")
    
    quotes = soup.find_all("div", class_="quote")
    for q in quotes:
        text = q.find("span", class_="text").get_text()
        author = q.find("small", class_="author").get_text()
        all_quotes.append([text, author])
    
    next_page = soup.find("li", class_="next")
    url = next_page.a["href"] if next_page else None

# 保存为CSV
with open("quotes.csv", "w", newline="", encoding="utf-8") as f:
    writer = csv.writer(f)
    writer.writerow(["Quote", "Author"])
    writer.writerows(all_quotes)

print("共爬取名言数:", len(all_quotes))

运行后,会得到一个包含全部名言的 quotes.csv 文件。


3. 程序说明

  • 循环分页:通过检测"下一页"链接实现多页抓取;

  • 异常处理 :实际项目中需加入 try-except 防止网络中断;

  • 存储格式:CSV方便后续导入Excel或Pandas分析;

  • 模拟浏览器头:若被屏蔽,可添加请求头:

    headers = {"User-Agent": "Mozilla/5.0"}
    requests.get(url, headers=headers)


四、进阶思考:从静态到动态网页

前面的例子属于静态网页爬取 ,即页面HTML中就包含所有目标数据。

但如今很多网站是动态加载 的,比如淘宝、知乎、微博,这些页面内容往往是通过 JavaScript 异步请求(AJAX) 动态生成的。

常见的应对方案包括:

  1. 抓取Ajax接口数据(通过Network分析请求)
  2. 使用Selenium或Playwright模拟浏览器
  3. 调用网站开放的API接口
  4. 混合方式:requests + JS渲染解析

例如,用Selenium打开动态网页并获取内容:

复制代码
from selenium import webdriver

driver = webdriver.Chrome()
driver.get("https://example.com")
html = driver.page_source
print(html)
driver.quit()

Selenium会完整加载网页,包括动态生成的内容。

五、反爬机制与应对策略

随着数据爬取越来越普遍,网站为了保护数据资源和防止滥用,纷纷部署了各种反爬机制(Anti-Crawling)

如果你在爬取某个网站时,突然发现返回空白页面、403错误,或数据异常,那多半是被反爬了。

1. 常见反爬手段

(1) User-Agent检测

服务器会根据请求头中的User-Agent判断访问来源。如果没有或是明显为程序请求的UA,就会被封锁。
解决方式: 随机更换UA。

复制代码
import random

headers = {
    "User-Agent": random.choice([
        "Mozilla/5.0 (Windows NT 10.0; Win64; x64)",
        "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)",
        "Mozilla/5.0 (iPhone; CPU iPhone OS 16_0 like Mac OS X)"
    ])
}
(2) IP封禁

高频访问会触发服务器的安全策略,临时或永久封禁IP。
解决方式:使用代理池或限速访问。

复制代码
import requests, time

proxies = {"http": "http://123.45.67.89:8080"}
for i in range(10):
    res = requests.get("https://example.com", proxies=proxies)
    time.sleep(2)
(3) Cookie与登录验证

部分网站要求用户登录后才能访问完整数据。
解决方式: 模拟登录获取Cookie,或使用 requests.Session() 保持会话。

复制代码
s = requests.Session()
s.post("https://site.com/login", data={"user": "xxx", "pwd": "123"})
res = s.get("https://site.com/data")
(4) 动态加载与加密参数

有的网站会把关键数据放在加密接口或JS动态渲染里。
解决方式:

  • 抓包分析网络请求(通过浏览器Network面板)
  • 逆向JS参数生成逻辑
  • 或使用Selenium执行JS获取结果
(5) 验证码(Captcha)

验证码是最常见的反爬屏障。
解决方式:

  • 手动输入(适合一次性任务)
  • OCR识别(如Tesseract)
  • 或调用打码平台API(需注意合法使用)

2. 合法与合规性原则

进行网络爬取时,一定要遵守以下原则:

  1. 仅采集公开数据(不抓取登录后或隐私数据);
  2. 遵守 robots.txt 协议
  3. 控制访问频率(建议 >1秒/次);
  4. 仅作学习与研究用途

记住一句话:

合法的爬虫是数据采集,非法的爬虫是攻击。


六、Scrapy 框架详解

在小项目中,我们可以用 requests + BeautifulSoup 实现简单爬取;

但面对上千网页、大量异步任务时,就需要使用更高效的爬虫框架。
Scrapy 是 Python 最主流的爬虫框架,具有速度快、结构清晰、扩展性强的优点。

1. Scrapy框架结构

Scrapy 的核心组件包括:

  • Spider(爬虫):定义如何抓取和解析网页;
  • Engine(引擎):负责调度与数据流转;
  • Scheduler(调度器):管理请求队列;
  • Downloader(下载器):负责网络请求;
  • Pipeline(管道):处理和存储数据。

数据流向如下:

复制代码
Spider -> Engine -> Scheduler -> Engine -> Downloader -> Engine -> Spider -> Pipeline

2. 创建Scrapy项目

命令行输入:

复制代码
scrapy startproject quotes_spider

目录结构:

复制代码
quotes_spider/
    spiders/
        quotes.py
    items.py
    pipelines.py
    settings.py

3. 编写爬虫

spiders/quotes.py 中:

复制代码
import scrapy

class QuotesSpider(scrapy.Spider):
    name = "quotes"
    start_urls = ["https://quotes.toscrape.com/page/1/"]

    def parse(self, response):
        for quote in response.css("div.quote"):
            yield {
                "text": quote.css("span.text::text").get(),
                "author": quote.css("small.author::text").get(),
            }

        next_page = response.css("li.next a::attr(href)").get()
        if next_page:
            yield response.follow(next_page, callback=self.parse)

执行爬虫:

复制代码
scrapy crawl quotes -o quotes.json

运行后,将自动抓取所有页面并保存为 quotes.json


4. 使用Pipeline存储数据

pipelines.py 中:

复制代码
import csv

class QuotesPipeline:
    def open_spider(self, spider):
        self.file = open('quotes.csv', 'w', newline='', encoding='utf-8')
        self.writer = csv.writer(self.file)
        self.writer.writerow(['Quote', 'Author'])

    def process_item(self, item, spider):
        self.writer.writerow([item['text'], item['author']])
        return item

    def close_spider(self, spider):
        self.file.close()

settings.py 启用管道:

复制代码
ITEM_PIPELINES = {
   'quotes_spider.pipelines.QuotesPipeline': 300,
}

Scrapy 会在每次抓取到数据后自动调用 process_item() 进行存储。


七、实战案例:京东商品评论爬取与情感分析

为了展示爬虫的应用场景,我们将实现一个综合项目

从京东商品页爬取评论数据,并进行情感分析。

1. 目标与工具

  • 爬取:京东笔记本电脑评论(JSON接口)
  • 解析:提取评论内容、评分、时间
  • 存储:CSV
  • 分析:基于TextBlob进行情感倾向分析

2. 网页分析

打开京东商品页 → 按F12 → Network → 搜索 comment

可找到评论接口,如:

复制代码
https://club.jd.com/comment/productPageComments.action?callback=fetchJSON_comment98&productId=100000177760&score=0&page=1&pageSize=10

这是一个标准的 JSON 接口,只需更换 page 参数即可翻页。

3. 代码实现

复制代码
import requests, json, csv, time

headers = {"User-Agent": "Mozilla/5.0"}
pid = "100000177760"
url = f"https://club.jd.com/comment/productPageComments.action?productId={pid}&score=0&page={{}}&pageSize=10"

comments = []

for page in range(0, 50):  # 前50页
    res = requests.get(url.format(page), headers=headers)
    text = res.text.strip("fetchJSON_comment98();")
    data = json.loads(text)
    for c in data["comments"]:
        comments.append([c["content"], c["creationTime"], c["score"]])
    time.sleep(1)

with open("jd_comments.csv", "w", newline="", encoding="utf-8") as f:
    writer = csv.writer(f)
    writer.writerow(["content", "time", "score"])
    writer.writerows(comments)

print("共爬取评论数:", len(comments))

4. 评论情感分析

使用 textblob(或SnowNLP中文版本)对评论做情感倾向分析。

复制代码
from snownlp import SnowNLP
import pandas as pd

df = pd.read_csv("jd_comments.csv")
df["sentiment"] = df["content"].apply(lambda x: SnowNLP(str(x)).sentiments)
df.to_csv("jd_comments_analyzed.csv", index=False)

print("平均情感倾向:", df["sentiment"].mean())

结果可以看到整体评论倾向(>0.6为积极,<0.4为消极)。


八、异步与分布式爬虫

1. 异步爬虫概念

传统爬虫是同步阻塞 的:一次只能处理一个请求。

异步爬虫(如 aiohttpasyncio)能并发数百上千请求,大幅提升速度。

示例:

复制代码
import aiohttp, asyncio

async def fetch(session, url):
    async with session.get(url) as res:
        return await res.text()

async def main():
    urls = [f"https://quotes.toscrape.com/page/{i}/" for i in range(1,6)]
    async with aiohttp.ClientSession() as session:
        tasks = [fetch(session, url) for url in urls]
        htmls = await asyncio.gather(*tasks)
        print("共抓取页面:", len(htmls))

asyncio.run(main())

2. 分布式爬虫

当爬取规模过大(如数百万网页)时,需要使用分布式系统:

  • Redis + Scrapy-Redis:任务分发与去重;
  • Kafka / RabbitMQ:消息队列管理;
  • MongoDB / Elasticsearch:数据存储与检索;
  • Celery:任务异步执行。

架构示意:

复制代码
Master节点:调度 + 任务分发
Worker节点:爬取 + 存储
Redis:任务队列 + URL去重
MongoDB:数据持久化

这种架构常用于电商、舆情监控、新闻聚合等大型数据采集系统。


九、总结与展望

通过本文,我们系统地学习了:

  1. 爬虫的原理与流程
  2. HTTP与HTML解析方法
  3. 静态与动态网页的区别
  4. 反爬机制与应对策略
  5. Scrapy框架的使用方法
  6. 京东评论爬取实战与情感分析
  7. 异步与分布式爬虫架构

爬虫的未来方向

  • 智能化爬虫:结合机器学习模型进行数据抽取与分类;
  • API爬取转向:更多数据迁移至API或私有接口;
  • 合规性与隐私保护:爬虫将更受法律约束;
  • 云端爬虫平台:如Scrapy Cloud、Apify、Colly将简化部署流程。

最后一句话

爬虫的本质是数据连接的艺术。掌握它,就掌握了打开互联网的钥匙。

相关推荐
一条星星鱼4 小时前
从0到1:如何用统计学“看透”不同睡眠PSG数据集的差异(域偏差分析实战)
人工智能·深度学习·算法·概率论·归一化·睡眠psg
香菜烤面包5 小时前
Attention:MHA->MQA->GQA->MLA
人工智能·深度学习
MediaTea5 小时前
Python 第三方库:Word Cloud(词云图生成)
开发语言·python
B站_计算机毕业设计之家5 小时前
python股票交易数据管理系统 金融数据 分析可视化 Django框架 爬虫技术 大数据技术 Hadoop spark(源码)✅
大数据·hadoop·python·金融·spark·股票·推荐算法
nju_spy5 小时前
牛客网 AI题(一)机器学习 + 深度学习
人工智能·深度学习·机器学习·lstm·笔试·损失函数·自注意力机制
weixin_432900375 小时前
口碑好的共晶贴片机公司
python·数码相机
如竟没有火炬5 小时前
全排列——交换的思想
开发语言·数据结构·python·算法·leetcode·深度优先
岁月的眸6 小时前
【循环神经网络基础】
人工智能·rnn·深度学习