Python项目实战——网络机器人(爬虫)

一、网络爬虫概述

1.1 什么是网络爬虫

网络爬虫(Web Crawler),也称网络机器人,是一种按照预设规则,自动浏览互联网并抓取网页数据的程序或脚本。它模拟人类浏览网页的行为,但效率极高,可以在短时间内遍历成千上万个页面。

爬虫的核心工作流程可以概括为四个步骤:

  • 开始:设定起始URL和抓取规则

  • 发送HTTP请求:向目标服务器请求页面内容

  • 解析结果提取数据:从HTML文档中抽取出所需信息

  • 数据处理与存储:清洗、整理并保存数据

1.2 爬虫的应用场景

爬虫技术广泛应用于多个领域:

  • 搜索引擎(如百度、Google)------抓取网页建立索引,支撑亿万级检索

  • 舆情监控------实时监测社交媒体、新闻网站的舆论动态

  • 商业分析(如电商比价系统)------采集商品价格、评论,辅助决策

  • AI大模型训练------收集海量文本语料,用于模型预训练

可以说,在大数据时代,爬虫是获取外部数据不可或缺的工具。

1.3 爬虫的合规性------robots协议

在编写爬虫之前,必须了解 robots协议 (也称爬虫协议、君子协议)。该协议是网站根目录下存放的 robots.txt 文本文件,用于告知爬虫哪些页面允许抓取,哪些禁止抓取。

下面以知名编程语言排行榜网站 TIOBE 的 robots.txt 为例:

复制代码
User-agent: *
Disallow: /wp-admin/
Allow: /wp-admin/admin-ajax.php
Sitemap: https://www.tiobe.com/sitemap_index.xml
Crawl-delay: 5

User-agent: Wandoujia Spider
Disallow: /

User-agent: Mediapartners-Google
Disallow: /subject_search
Disallow: /amazon_search

关键字段含义:

  • User-agent:标识爬虫身份(* 表示所有爬虫)

  • Disallow:禁止访问的资源路径

  • Allow:允许访问的资源路径

  • Sitemap:网站地图地址,帮助爬虫发现页面

  • Crawl-delay:请求间隔时间(秒),避免对服务器造成压力

请务必遵守 robots.txt 的约定,这是爬虫开发者基本的职业道德。虽然它是"君子协议"而非法律强制,但遵守它既是尊重网站所有者,也是保护自己免受法律风险。

二、入门程序:发送HTTP请求

2.1 安装 requests 库

Python 中最流行的 HTTP 客户端库是 requests,它让发送网络请求变得极其简单。安装命令:

复制代码
pip install requests

2.2 发送请求获取网页

我们以获取 TIOBE 编程语言排行榜页面为例:

复制代码
import requests

url = "https://www.tiobe.com/tiobe-index/"
headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
}

response = requests.get(url, headers=headers)
print(response.status_code)  # 200 表示成功
print(response.text[:500])   # 打印前500字符的HTML

关键点

  • requests.get() 发送 GET 请求

  • headers 参数设置 User-Agent,模拟浏览器访问,避免被识别为爬虫

  • response.text 返回服务器响应的 HTML 源代码

仅需几行代码,我们就成功获取了网页的完整内容,为后续解析提供了原始素材。

三、网页结构基础

3.1 网页的三部分:HTML、CSS、JS

一个网页由三个核心技术共同构成:

组成部分 全称 作用
HTML 超文本标记语言 负责网页的结构(页面元素和内容)
CSS 层叠样式表 负责网页的表现(样式、颜色、位置、大小)
JS JavaScript 负责网页的行为(交互效果、动态更新)

这三者各司其职:HTML 搭建骨架,CSS 美化外观,JS 赋予生命力。

3.2 HTML 基本语法

HTML(HyperText Markup Language)是一种超文本标记语言 。"超文本"意味着它不仅包含文字,还可以定义图片、音频、视频等内容。"标记语言"则是指由一堆预定义的标签构成,如 <h1><p><a> 等。

一个简单的 HTML 示例:

复制代码
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>仙逆人物志 - 修真世界</title>
</head>
<body>
    <h1>Python</h1>
    <p>一门简洁、快速、易用的编程语言。</p>
    <a href="https://www.itcast.cn">传智教育-黑马程序员</a>
</body>
</html>

标签规则

  • 标签通常成对出现:<标签名> 内容 </标签名>(开始标签 + 结束标签)

  • 标签可以拥有属性 ,如 <a href="..."> 中的 href 指定链接地址

  • HTML 代码直接在浏览器中运行,由浏览器解析并渲染

爬虫的核心任务就是从这些标签的海洋中,精准定位并提取我们需要的数据。

四、网页解析:XPath 与 lxml

4.1 什么是网页解析

网页解析是指从原始 HTML 文档中提取数据的过程,也是网络爬虫的关键步骤。我们需要从一堆标签和文本中,抽取出目标信息(如标题、价格、评分等)。

4.2 安装 lxml 库

lxml 是 Python 中高性能的 HTML/XML 解析库,支持基于 XPath 语法来解析和提取网页数据。安装命令:

复制代码
pip install lxml

4.3 XPath 语法详解

XPath(XML Path Language)是一种在 HTML/XML 文档中导航定位元素的查询语言,能让你准确地定位文档中的特定元素、属性或文本。

常见 XPath 表达式及含义:

XPath 表达式 含义
/html/head/title[1] 选择 <html><head> 中的第一个 <title> 元素
//div/a/text() 选择文档中所有 <div> 下的 <a> 标签的文本内容
//div/a/@href 选择所有 <div> 下的 <a> 标签的 href 属性值
//div/a[@target='_blank'] 选择所有 target 属性值为 _blank<a> 标签
//div[2]/p[last()]/text() 选择第二个 <div> 下最后一个 <p> 标签的文本

要点

  • / 表示从根节点开始(绝对路径)

  • // 表示在文档任意位置搜索(相对路径)

  • [ ] 用于添加条件(索引、属性筛选等)

  • text() 提取标签内的文本

  • @属性名 提取标签的属性值

4.4 使用 lxml 提取数据

复制代码
from lxml import html

# 加载HTML文件
with open("resources/仙逆人物志.html", "r", encoding="utf-8") as f:
    html_content = f.read()

# 解析为文档对象
doc = html.fromstring(html_content)

# 使用XPath提取数据
th_list = doc.xpath("//table/thead/tr[1]/th/text()")
td_list = doc.xpath("//table/tbody/tr[1]/td/text()")

print("表头:", th_list)
print("第一行数据:", td_list)

html.fromstring() 将 HTML 字符串解析为可执行 XPath 查询的文档对象,然后通过 xpath() 方法直接提取目标数据,返回列表。

五、案例实战:获取高分电影榜单

5.1 案例目标与步骤

本案例的目标是从 The Movie Database (TMDB) 获取高分电影 Top100 数据,并保存为 CSV 文件。

需要提取的字段包括:

  • 电影名、年份、上映时间、类型、时长、评分、语言

  • 导演、作者、主演、Slogan、简介

实现步骤如下:

  1. 查看目标网站的 robots.txt,确认抓取规则

  2. 分析页面结构,确定数据在 HTML 中的位置

  3. 获取电影列表页,提取每部电影的详情页链接

  4. 遍历每一部电影的详情页,提取全部所需字段

  5. 对提取到的原始数据进行清洗(如处理年份、时长格式)

  6. 将清洗后的数据写入 CSV 文件

5.2 数据清洗------正则表达式

在实际抓取中,原始数据往往不够"干净"。例如:

  • 年份字段可能是 19941994-09-231994 (USA)

  • 时长可能是 144 分钟2h 24min144

  • 评分可能包含多余字符

我们需要从中提取出纯净的数字或标准格式。这时就要用到正则表达式(Regular Expression)。

正则表达式是一种用特定语法规则组成的字符串模式,用来描述、匹配或替换文本中符合某种规则的字符序列。可以理解为专门用于文本处理的"高级查找和匹配公式"。

Python re 模块三大函数

函数 作用
match(pattern, string) 从字符串开头开始匹配
search(pattern, string) 从任意位置搜索第一个匹配项
findall(pattern, string) 从任意位置搜索所有匹配项,返回列表

注意 :字符串前的 r 表示原始字符串,使转义字符无效,如 r"\d" 就是反斜杠和 d 两个字符,而非转义。

5.3 正则表达式语法速查

语法 含义
. 匹配任意单个字符(除换行符)
\d 匹配数字,\D 匹配非数字
\w 匹配字母、数字、下划线,\W 匹配非单词字符
\s 匹配空白字符,\S 匹配非空白
* 匹配前一个字符 0次或多次
+ 匹配前一个字符 1次或多次
? 匹配前一个字符 0次或1次
{m} 匹配前一个字符 恰好 m 次
{m,} 匹配前一个字符 至少 m 次
{m,n} 匹配前一个字符 m 到 n 次
` `
() 分组,捕获子表达式
^ 匹配字符串开头
$ 匹配字符串结尾

实用示例

  • 匹配手机号:1[3-9]\d{9}(1开头,第二位3-9,后面9位数字)

  • 匹配年份:\d{4}(四位数字)

  • 提取数字:\d+(一个或多个数字)

5.4 完整代码实现

下面给出案例的核心代码框架,实际项目中需根据页面结构调整 XPath。

复制代码
import requests
from lxml import html
import csv
import re

# 目标网站(请先查看其 robots.txt)
BASE_URL = "https://www.themoviedb.org"
LIST_URL = BASE_URL + "/top-rated"

headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"}

# 1. 获取列表页
resp = requests.get(LIST_URL, headers=headers)
doc = html.fromstring(resp.text)

# 2. 提取每部电影的详情页链接(假设链接在 class='title' 的 a 标签的 href 属性中)
movie_links = doc.xpath("//a[@class='title']/@href")

all_movies = []

# 3. 遍历前100部电影
for link in movie_links[:100]:
    detail_url = BASE_URL + link
    detail_resp = requests.get(detail_url, headers=headers)
    detail_doc = html.fromstring(detail_resp.text)
    
    # 4. 提取各字段(以下 XPath 仅为示例,需根据实际页面调整)
    title = detail_doc.xpath("//h2[@class='title']/text()")[0] if detail_doc.xpath("//h2[@class='title']/text()") else ""
    
    # 年份处理:提取四位数字
    raw_year = detail_doc.xpath("//span[@class='year']/text()")[0] if detail_doc.xpath("//span[@class='year']/text()") else ""
    year = re.search(r"\d{4}", raw_year).group() if re.search(r"\d{4}", raw_year) else ""
    
    # 时长处理:提取数字
    raw_runtime = detail_doc.xpath("//span[@class='runtime']/text()")[0] if detail_doc.xpath("//span[@class='runtime']/text()") else ""
    runtime = re.search(r"\d+", raw_runtime).group() if re.search(r"\d+", raw_runtime) else ""
    
    # 评分
    rating = detail_doc.xpath("//span[@class='rating']/text()")[0] if detail_doc.xpath("//span[@class='rating']/text()") else ""
    
    # 其他字段(导演、主演等)类似处理...
    
    # 5. 收集数据
    all_movies.append([title, year, runtime, rating])  # 仅示例,实际要包含全部字段

# 6. 写入CSV文件
with open("top100_movies.csv", "w", encoding="utf-8", newline="") as f:
    writer = csv.writer(f)
    writer.writerow(["电影名", "年份", "时长(分钟)", "评分"])  # 表头
    writer.writerows(all_movies)

print(f"成功抓取 {len(all_movies)} 部电影数据,已保存到 top100_movies.csv")

CSV 说明:CSV(Comma-Separated Values,逗号分隔值)是一种简单通用的文本文件格式,用于存储表格数据,可直接用 Excel 打开。

六、总结

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

  • 爬虫的基本概念与应用场景

  • robots.txt 君子协议及其关键字段

  • requests 库发送 HTTP 请求

  • HTML/CSS/JS 网页结构与标签语法

  • XPath 与 lxml 解析网页并提取数据

  • 正则表达式进行文本清洗与格式化

  • 一个完整的电影榜单爬取案例(从列表到详情,再到 CSV 存储)

爬虫是数据获取的重要手段,但也是一把双刃剑。在实际开发中,请牢记:

  1. 遵守 robots.txt,尊重网站规则

  2. 控制请求频率,设置合理的间隔(如 Crawl-delay),避免给服务器造成负担

  3. 合理使用数据,不侵犯他人权益

  4. 动态反爬 是常见挑战,后续可学习 Selenium、代理IP、异步请求等进阶技术

技术无好坏,但使用技术的人要有底线。愿你在爬虫的世界里,既收获数据,也守住道德。

Happy Coding!🐍

Happy Coding!🐍

Happy Coding!🐍

相关推荐
用户298698530143 小时前
Python 实现 Excel 到 ODS、XPS、PostScript 及 PDF/A-1b 的格式转换
后端·python·excel
本地化文档3 小时前
xlwings-docs-l10n
python·github·excel·gitcode·sphinx
深圳慧闻智造技术有限公司3 小时前
从宇树G1做手术登Nature,看机器人精密零件加工的四大难点与核心能力
机器人·精密零件加工·机器人零件加工·精密机械加工
ZPC82103 小时前
model bingxing
网络·人工智能·网络协议·机器人
梅雅达编程笔记3 小时前
零基础学 Python 第7章 | 字典 dict:键值对存储
开发语言·python·beautifulsoup·numpy·pandas
heroboyluck3 小时前
AI工程师第四课 - 深度学习入门
人工智能·python·深度学习·llama
alicema11114 小时前
BRAIN 研究顾问(Research Consultant)兼职
python·量化
元Y亨H4 小时前
Python,单引号和双引号有何区别
python
超神熊猫4 小时前
🧀🧀🧀前端仔如何快速上手python
前端·python