跳转到主要内容
杨月昌的软件博客
返回

Python 爬虫实战:Requests + 正则表达式抓取猫眼电影 TOP 100

1. 爬虫架构设计

在不使用复杂框架(如 Scrapy)的情况下,一个轻量级爬虫的执行逻辑通常分为四个核心环节:


2. 核心步骤详解

2.1 获取网页内容

现代网站通常会有基础的防爬检测。除了 User-Agent,我们有时还需要添加 Host 来提高请求的真实性。

2.2 正则表达式的“解剖学”

正则表达式虽然强大,但难以阅读。在本项目中,我们匹配的是 <dd> 标签内的层级结构。

2.3 并发爬取效率对比


3. 完整代码实现

import requests
from requests.exceptions import RequestException
import re
import json
from multiprocessing import Pool

def get_one_page(url):
    """获取单页 HTML 源码"""
    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',
        'Host': 'www.maoyan.com',
        'Referer': 'https://www.maoyan.com/board/4'
    }
    try:
        response = requests.get(url, headers=headers, timeout=10)
        if response.status_code == 200:
            return response.text
        return None
    except RequestException as e:
        print(f"请求异常: {e}")
        return None

def parse_one_page(html):
    """
    使用正则表达式解析。
    建议:在实际开发中,如果 HTML 结构极其复杂,可考虑使用 BeautifulSoup 或 lxml
    """
    pattern = re.compile(
        '<dd>.*?board-index.*?>(\d+)</i>'        # 排名
        +'.*?data-src="(.*?)"'                   # 封面图
        +'.*?name"><a.*?>(.*?)</a>'             # 电影名
        +'.*?star">(.*?)</p>'                   # 主演
        +'.*?releasetime">(.*?)</p>'            # 上映时间
        +'.*?integer">(.*?)</i>'                # 评分整数
        +'.*?fraction">(.*?)</i>.*?</dd>',      # 评分小数
        re.S
    )
    items = re.findall(pattern, html)
    for item in items:
        yield {
            'index': item[0],
            'image': item[1],
            'title': item[2].strip(),
            'actor': item[3].strip()[3:] if len(item[3]) > 3 else '',
            'time': item[4].strip()[5:] if len(item[4]) > 5 else '',
            'score': item[5].strip() + item[6].strip()
        }

def write_to_file(content):
    """将结果追加写入 JSON Lines 文件"""
    with open('result.jsonl', 'a', encoding='utf-8') as f:
        f.write(json.dumps(content, ensure_ascii=False) + '\n')

def main(offset):
    url = f'https://www.maoyan.com/board/4?offset={offset}'
    html = get_one_page(url)
    if html:
        for item in parse_one_page(html):
            print(f"正在抓取排名 {item['index']}: {item['title']}")
            write_to_file(item)

if __name__ == '__main__':
    # 设定进程池,建议大小根据 CPU 核心数调整
    pool = Pool()
    offsets = [i * 10 for i in range(10)]
    pool.map(main, offsets)
    pool.close()
    pool.join()

4. 关键技术点分析


5. 总结

Requests + Re 的组合虽然原始,但它是理解爬虫底层原理的最佳途径。通过本项目,我们掌握了:

  1. 如何构造合法的 HTTP 请求头。
  2. 如何利用正则的贪婪与非贪婪匹配提取字段。
  3. 如何利用多进程压榨硬件性能。

温馨提示:在爬取任何网站时,请务必遵守该站的 robots.txt 协议,尊重版权,切勿用于商业非法用途。



上一篇
C# / WPF 实现软件开机自启动的深度指南:两种核心方案解析
下一篇
WPF 实战指南:从零构建工业级登录系统