Python爬虫零基础衔接进阶知识点详解【进阶版】

✅ 无缝衔接基础版内容,从“爬取静态/简单动态网页”到“应对企业级爬虫场景”过渡
✅ 技术适配:基于Python 3.12 + Scrapy框架 + 反爬突破 + 异步爬虫 + 数据存储进阶 + 分布式爬虫入门,聚焦高并发、反爬应对、规模化爬取三大核心场景
✅ 白话拆解+代码示例+实战场景,无冗余知识点,零基础可理解、可落地
✅ 核心目标:掌握企业级爬虫开发必备技能,能应对反爬机制、实现高效爬取、完成规模化数据采集


一、进阶学习核心定位

基础版聚焦“入门级爬取+基础数据存储”,进阶版核心解决:
✅ 效率提升:从单线程同步爬取到异步/多线程爬取,效率提升10倍+
✅ 反爬突破:应对常见反爬机制(IP封禁、验证码、Cookie验证、JS加密)
✅ 工程化落地:掌握Scrapy框架、分布式爬虫、数据去重/清洗、爬虫监控
✅ 合规与稳定:构建健壮的爬虫体系,避免被封、数据丢失


二、第一部分:爬虫效率进阶

1. 异步爬虫(aiohttp)

基础版的Requests是同步请求(一个请求完成再发下一个),异步爬虫可同时发送多个请求,大幅提升爬取效率,适合大批量数据采集。

核心代码示例:
import aiohttp
import asyncio
from bs4 import BeautifulSoup

# 异步请求函数
async def fetch_url(session, url):
    headers = {"User-Agent": "Chrome/120.0.0.0"}
    try:
        async with session.get(url, headers=headers, timeout=10) as response:
            if response.status == 200:
                html = await response.text()
                return parse_html(html)  # 解析数据
            return None
    except Exception as e:
        print(f"请求失败:{url},错误:{e}")
        return None

# 数据解析函数
def parse_html(html):
    soup = BeautifulSoup(html, "lxml")
    title = soup.title.text.strip()
    return title

# 主异步函数
async def main(urls):
    # 创建异步会话
    async with aiohttp.ClientSession() as session:
        # 批量创建任务
        tasks = [fetch_url(session, url) for url in urls]
        # 执行所有任务
        results = await asyncio.gather(*tasks)
        # 过滤空结果
        valid_results = [res for res in results if res]
        print(f"成功爬取 {len(valid_results)} 个页面")
        print(valid_results[:5])

if __name__ == "__main__":
    # 待爬取的URL列表
    test_urls = [f"https://book.douban.com/top250?start={i*25}" for i in range(10)]
    # 运行异步程序
    asyncio.run(main(test_urls))
关键要点:
  • 核心库:aiohttp(异步HTTP请求)、asyncio(异步任务调度);
  • 语法规则:异步函数用async def定义,耗时操作前加await
  • 优势:批量请求时效率远超同步爬虫,适合爬取海量URL。

2. 多线程/多进程爬虫

多线程:同一进程下同时运行多个任务,适合IO密集型(如网络请求);
多进程:利用多核CPU,适合CPU密集型(如大量数据解析)。

多线程示例(threading):
import requests
from bs4 import BeautifulSoup
import threading
import queue

# 队列存储URL(线程安全)
url_queue = queue.Queue()
# 结果存储(加锁避免冲突)
result_list = []
lock = threading.Lock()

# 线程任务函数
def crawl_worker():
    headers = {"User-Agent": "Chrome/120.0.0.0"}
    while not url_queue.empty():
        url = url_queue.get()
        try:
            response = requests.get(url, headers=headers, timeout=5)
            response.encoding = "utf-8"
            soup = BeautifulSoup(response.text, "lxml")
            title = soup.title.text.strip()
            # 加锁写入结果
            with lock:
                result_list.append(title)
        except Exception as e:
            print(f"爬取失败:{url},错误:{e}")
        finally:
            url_queue.task_done()

if __name__ == "__main__":
    # 填充URL队列
    for i in range(10):
        url_queue.put(f"https://book.douban.com/top250?start={i*25}")
    
    # 创建5个线程
    threads = []
    for _ in range(5):
        t = threading.Thread(target=crawl_worker)
        t.start()
        threads.append(t)
    
    # 等待所有线程完成
    for t in threads:
        t.join()
    
    print(f"爬取完成,共获取 {len(result_list)} 个标题")
    print(result_list[:5])
关键要点:
  • 线程安全:用queue.Queue存储URL,threading.Lock保护共享数据;
  • 适用场景:多线程适合爬虫(IO密集),多进程适合数据处理(CPU密集);
  • 注意:避免创建过多线程(建议10-20个),否则会引发连接异常。

三、第二部分:反爬机制突破

1. IP代理池(应对IP封禁)

网站会限制单一IP的请求频率,代理池可切换不同IP发送请求,避免被封。

核心实现:
import requests

# 代理池(可对接免费/付费代理接口)
proxies_list = [
    {"http": "http://123.45.67.89:8080", "https": "https://123.45.67.89:8080"},
    {"http": "http://98.76.54.32:8080", "https": "https://98.76.54.32:8080"}
]

def crawl_with_proxy(url):
    headers = {"User-Agent": "Chrome/120.0.0.0"}
    # 随机选择代理
    import random
    proxy = random.choice(proxies_list)
    try:
        # 超时控制+代理请求
        response = requests.get(url, headers=headers, proxies=proxy, timeout=10)
        print(f"代理 {proxy['http']} 请求成功,状态码:{response.status_code}")
        return response.text
    except Exception as e:
        print(f"代理 {proxy['http']} 请求失败:{e}")
        return None

# 测试
crawl_with_proxy("https://httpbin.org/ip")  # 查看当前IP
关键要点:
  • 代理类型:免费代理(稳定性差)、付费代理(如阿布云、快代理,企业级首选);
  • 代理验证:爬取https://httpbin.org/ip验证代理是否生效;
  • 异常处理:代理失效时自动切换下一个,避免程序中断。

2. 验证码处理(入门级)

2.1 手动打码(简单场景)
from selenium import webdriver
from selenium.webdriver.common.by import By
import time

driver = webdriver.Chrome()
driver.get("https://www.xxx.com/login")

# 等待用户手动输入验证码
time.sleep(10)  # 10秒内完成验证码输入+登录

# 后续爬取逻辑
...
driver.quit()
2.2 第三方打码平台(如超级鹰,自动化处理)
import requests
from PIL import Image
import base64

# 1. 下载验证码图片
captcha_url = "https://www.xxx.com/captcha.jpg"
response = requests.get(captcha_url)
with open("captcha.jpg", "wb") as f:
    f.write(response.content)

# 2. 调用超级鹰接口识别(需注册账号)
def recognize_captcha(image_path):
    api_url = "http://upload.chaojiying.net/Upload/Processing.php"
    params = {
        "user": "你的账号",
        "pass": "你的密码",
        "softid": "你的软件ID",
        "codetype": "1004"  # 验证码类型(数字+字母)
    }
    with open(image_path, "rb") as f:
        files = {"userfile": f}
        response = requests.post(api_url, data=params, files=files)
    result = response.json()
    return result["pic_str"] if result["err_no"] == 0 else None

# 3. 获取识别结果
captcha_code = recognize_captcha("captcha.jpg")
print(f"验证码识别结果:{captcha_code}")

3. Cookie与Session保持

部分网站需要登录后才能爬取,通过Session保持登录状态,避免重复登录。

import requests

# 创建Session(自动保持Cookie)
session = requests.Session()
headers = {"User-Agent": "Chrome/120.0.0.0"}

# 1. 登录(获取Cookie)
login_url = "https://www.xxx.com/login"
login_data = {
    "username": "你的账号",
    "password": "你的密码"
}
session.post(login_url, data=login_data, headers=headers)

# 2. 爬取需要登录的页面(自动携带Cookie)
user_center_url = "https://www.xxx.com/user-center"
response = session.get(user_center_url, headers=headers)
print(response.text)  # 已登录后的内容

四、第三部分:工程化爬虫(Scrapy框架)

1. Scrapy核心优势

  • 内置异步处理、数据解析、数据存储、反爬配置;
  • 模块化设计,支持中间件、扩展,适合规模化爬虫开发;
  • 内置日志、统计、断点续爬等功能,企业级必备。

2. Scrapy入门实战(爬取豆瓣书籍)

步骤1:创建Scrapy项目
# 创建项目
scrapy startproject douban_spider
# 创建爬虫
cd douban_spider
scrapy genspider book book.douban.com
步骤2:编写爬虫代码(douban_spider/spiders/book.py)
import scrapy

class BookSpider(scrapy.Spider):
    name = "book"  # 爬虫名
    allowed_domains = ["book.douban.com"]  # 允许爬取的域名
    start_urls = ["https://book.douban.com/top250"]  # 起始URL

    def parse(self, response):
        # 解析书籍列表(XPath语法)
        book_items = response.xpath('//tr[@class="item"]')
        for item in book_items[:10]:
            # 提取数据(XPath/CSSelector均可)
            yield {
                "rank": item.xpath('.//em/text()').extract_first(),
                "name": item.xpath('.//div[@class="pl2"]/a/@title').extract_first(),
                "score": item.xpath('.//span[@class="rating_nums"]/text()').extract_first(),
                "link": item.xpath('.//div[@class="pl2"]/a/@href').extract_first()
            }
        
        # 翻页(爬取下一页)
        next_page = response.xpath('//a[@class="next"]/@href').extract_first()
        if next_page:
            yield scrapy.Request(url=response.urljoin(next_page), callback=self.parse)
步骤3:配置反爬(settings.py)
# 设置User-Agent
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"
# 延迟请求(避免过快)
DOWNLOAD_DELAY = 2
# 启用Cookie保持
COOKIES_ENABLED = True
# 日志级别
LOG_LEVEL = "INFO"
步骤4:运行爬虫+存储数据
# 运行爬虫,保存为CSV
scrapy crawl book -o books.csv
# 保存为JSON
scrapy crawl book -o books.json

3. Scrapy中间件(自定义反爬策略)

示例:添加代理中间件(middlewares.py)
class ProxyMiddleware:
    def process_request(self, request, spider):
        # 随机添加代理
        proxies = [
            "http://123.45.67.89:8080",
            "http://98.76.54.32:8080"
        ]
        import random
        request.meta["proxy"] = random.choice(proxies)
在settings.py启用中间件:
DOWNLOADER_MIDDLEWARES = {
    "douban_spider.middlewares.ProxyMiddleware": 543,
}

五、第四部分:数据处理进阶

1. 数据去重

import pandas as pd

# 读取爬取的数据
df = pd.read_csv("books.csv")
# 按书名去重(保留第一条)
df = df.drop_duplicates(subset=["name"], keep="first")
# 重置索引
df = df.reset_index(drop=True)
# 保存去重后的数据
df.to_csv("books_unique.csv", index=False)
print(f"去重前:{len(df)+len(df[df.duplicated(subset=['name'])])} 条,去重后:{len(df)} 条")

2. 数据清洗(处理缺失值/异常值)

import pandas as pd

df = pd.read_csv("books.csv")
# 处理缺失值(删除/填充)
df = df.dropna(subset=["name", "score"])  # 删除书名/评分缺失的行
df["score"] = df["score"].fillna(0)  # 填充评分缺失值为0

# 处理异常值(如评分超出0-10范围)
df = df[(df["score"] >= 0) & (df["score"] <= 10)]

# 保存清洗后的数据
df.to_csv("books_clean.csv", index=False)

3. 数据库存储(MySQL/MongoDB)

3.1 存储到MySQL(Scrapy示例)
# pipelines.py
import pymysql

class MySQLPipeline:
    def open_spider(self, spider):
        # 连接数据库
        self.conn = pymysql.connect(
            host="localhost",
            user="root",
            password="你的密码",
            database="spider_db",
            charset="utf8mb4"
        )
        self.cursor = self.conn.cursor()

    def process_item(self, item, spider):
        # 插入数据
        sql = "INSERT INTO books (rank, name, score, link) VALUES (%s, %s, %s, %s)"
        self.cursor.execute(sql, (item["rank"], item["name"], item["score"], item["link"]))
        self.conn.commit()
        return item

    def close_spider(self, spider):
        # 关闭连接
        self.cursor.close()
        self.conn.close()
3.2 存储到MongoDB(Scrapy示例)
# pipelines.py
import pymongo

class MongoPipeline:
    def open_spider(self, spider):
        self.client = pymongo.MongoClient("mongodb://localhost:27017/")
        self.db = self.client["spider_db"]
        self.collection = self.db["books"]

    def process_item(self, item, spider):
        self.collection.insert_one(dict(item))
        return item

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

六、核心避坑清单

  1. ❌ 异步爬虫未做超时控制 → ✅ 添加timeout参数,避免请求挂起;
  2. ❌ 代理池无验证机制 → ✅ 定期检测代理有效性,剔除失效代理;
  3. ❌ Scrapy爬取时忽略allowed_domains → ✅ 严格配置允许的域名,避免爬取无关网站;
  4. ❌ 数据存储未做去重 → ✅ 爬取后先去重再入库,避免数据冗余;
  5. ❌ 高并发爬取无限流 → ✅ 设置DOWNLOAD_DELAY或限速中间件,避免被封;
  6. ❌ 忽略网站反爬升级 → ✅ 定期测试爬虫,及时调整反爬策略。

七、总结

  1. 效率提升核心:异步(aiohttp)、多线程适合大批量爬取,Scrapy框架是企业级爬虫的首选;
  2. 反爬突破关键:IP代理池解决IP封禁,Session保持登录状态,验证码可通过手动/第三方平台处理;
  3. 工程化落地:Scrapy的中间件、管道机制可实现模块化开发,适配复杂爬取场景;
  4. 数据处理重点:爬取后必须做去重、清洗,保证数据质量,按需选择CSV/MySQL/MongoDB存储。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IT=>小脑虎

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值