Python 爬虫入门基础教程:从入门到实践

文章目录

Python 爬虫入门基础教程:从入门到实践

一、爬虫入门第一课:认识爬虫

1.1 什么是爬虫?

爬虫 (Web Spider)本质上是一个自动获取网页数据的程序。你可以把它想象成一个"网络机器人":它会模拟人类浏览器的行为,访问互联网上的网页,然后按照你设定的规则,自动提取你需要的信息(比如新闻标题、商品价格、图片等),最后把这些信息整理保存下来。

举个最简单的例子:你想收集某网站上所有的Python教程标题,手动复制粘贴需要花1小时,而写一个爬虫程序,只需要10秒钟就能完成。

1.2 爬虫的作用和常见应用场景

  • 数据收集:收集新闻、天气、股票、招聘信息等

  • 数据分析:电商商品价格对比、用户评论分析、市场调研

  • 内容聚合:新闻聚合网站、搜索引擎

  • 自动化任务:自动签到、自动下载资源

1.3 学习爬虫需要的Python基础

你已经掌握了Python基本语法,这就足够入门了!具体需要用到的知识点:

  • 变量和基本数据类型(字符串、列表、字典)

  • 条件判断(if-else)和循环(for、while)

  • 函数的定义和调用

  • 基本的文件操作(读写文件)

  • 异常处理(try-except,后面会简单讲解)

1.4 爬虫的合法性和道德规范(非常重要!)

爬虫不是法外之地,在编写和运行爬虫之前,你必须遵守以下规则:

  1. 遵守robots协议 :网站根目录下的robots.txt文件会明确告诉爬虫哪些页面可以爬取,哪些不可以。例如:https://www.baidu.com/robots.txt

  2. 不要爬取敏感信息:个人隐私、商业机密、国家机密等信息绝对不能爬取

  3. 控制爬取频率:不要短时间内发送大量请求,以免给服务器造成过大压力

  4. 不要用于商业用途:未经授权的商业用途可能会引发法律纠纷

  5. 尊重版权:爬取的内容不要随意传播和商用

违反以上规则可能会导致你的IP被封禁,甚至承担法律责任!

二、爬虫核心基础:原理与流程

2.1 HTTP协议基础(爬虫的"语言")

浏览器和服务器之间是通过HTTP协议进行通信的,爬虫本质上就是模拟这个通信过程。你只需要掌握以下核心概念:

2.1.1 请求方法
  • GET :最常用的方法,用于获取数据。当你在浏览器地址栏输入网址访问页面时,发送的就是GET请求

  • POST :用于提交数据。比如登录账号、提交表单时发送的就是POST请求

2.1.2 请求头(Request Headers)

请求头是浏览器发送给服务器的"身份信息",告诉服务器"我是谁"。其中最重要的字段是:

  • User-Agent:标识浏览器的类型和版本。如果爬虫不设置这个字段,服务器很容易识别出这是一个爬虫程序,从而拒绝你的请求

  • Cookie:用于记录用户的登录状态。爬取需要登录的网站时需要用到

2.1.3 响应状态码

服务器返回的状态码,告诉我们请求的结果:

  • 200 OK:请求成功

  • 404 Not Found:页面不存在

  • 403 Forbidden:服务器拒绝访问(可能被识别为爬虫)

  • 500 Internal Server Error:服务器内部错误

2.1.4 Cookie和Session
  • Cookie:存储在用户浏览器中的一小段数据,用于记录用户的身份和状态

  • Session:存储在服务器端的数据,和Cookie一一对应,用于识别用户

简单来说:当你登录一个网站后,服务器会给你一个Cookie,之后你每次访问该网站,浏览器都会带上这个Cookie,服务器就能知道"你已经登录了"。

2.2 爬虫的整体工作流程

所有爬虫,无论简单还是复杂,都遵循以下5个基本步骤:

  1. 发送请求:向目标网站的服务器发送HTTP请求

  2. 获取响应:服务器返回网页的HTML代码

  3. 解析网页:从HTML代码中提取我们需要的数据

  4. 数据存储:将提取到的数据保存到文件或数据库中

  5. (可选)翻页/循环:重复以上步骤,爬取更多页面的数据

2.3 网页分析方法(爬虫的"眼睛")

这是爬虫入门最重要的技能!我们需要学会使用浏览器开发者工具来分析网页结构和网络请求。

2.3.1 打开开发者工具

在任意网页上按F12键,或者右键点击页面选择"检查",即可打开开发者工具。

2.3.2 Elements面板:查看和分析HTML结构

Elements面板显示了网页的完整HTML代码,我们可以在这里定位需要提取的元素。

  • 快速定位元素:点击Elements面板左上角的箭头图标,然后点击页面上你想要提取的内容,Elements面板会自动定位到对应的HTML代码

  • 查看元素属性 :在HTML代码中可以看到元素的标签名(如<div><p><a>)、类名(class)、ID(id)等属性,这些都是我们定位元素的依据

2.3.3 Network面板:分析网络请求

Network面板记录了浏览器和服务器之间的所有通信过程,是分析动态网页和API的利器。

  • 打开Network面板,刷新页面,就能看到所有的请求

  • 点击任意一个请求,可以查看请求的详细信息:请求方法、请求头、请求参数、响应内容等

  • 筛选请求:可以通过上方的筛选栏筛选出XHR(AJAX请求)、JS、CSS、图片等不同类型的请求

三、爬虫必备工具库详解

3.1 requests库:发送HTTP请求的神器

requests是Python最流行的HTTP请求库,它的API非常简洁易用,完全替代了Python内置的urllib库。

3.1.1 安装
Bash 复制代码
pip install requests
3.1.2 基本使用
Python 复制代码
import requests

# 1. 发送GET请求
response = requests.get("https://www.baidu.com")

# 2. 获取响应内容
print(response.status_code)  # 打印状态码
print(response.text)         # 打印网页HTML代码(字符串形式)
print(response.content)      # 打印网页二进制内容(用于下载图片、文件等)

# 3. 设置请求头(最重要!伪装成浏览器)
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"
}
response = requests.get("https://www.baidu.com", headers=headers)

# 4. 带参数的GET请求
# 相当于访问:https://www.baidu.com/s?wd=python
params = {"wd": "python"}
response = requests.get("https://www.baidu.com/s", headers=headers, params=params)

# 5. 发送POST请求
data = {"username": "admin", "password": "123456"}
response = requests.post("https://example.com/login", headers=headers, data=data)
3.1.3 常见问题
  • 乱码问题 :如果response.text显示乱码,可以手动设置编码:

    Python 复制代码
    response.encoding = "utf-8"  # 或者"gbk",根据网页实际编码设置
  • 超时设置:防止请求长时间卡住:

    Python 复制代码
    response = requests.get("https://www.baidu.com", headers=headers, timeout=10)

小练习:使用requests库访问你最喜欢的网站,打印出它的状态码和HTML代码。

3.2 lxml库 + XPath:最强大的网页解析工具

XPath是一种在XML/HTML文档中查找信息的语言,它的语法简洁、功能强大,是爬虫中最常用的元素定位方法。lxml是Python中解析HTML最快的库,完美支持XPath语法。

3.2.1 安装
Bash 复制代码
pip install lxml
3.2.2 基本使用流程
Python 复制代码
from lxml import etree

# 1. 将HTML字符串转换为lxml的Element对象
html = """
<div class="container">
    <h1 id="title">Python爬虫教程</h1>
    <ul class="course-list">
        <li class="course-item"><a href="/course/1">基础语法</a></li>
        <li class="course-item"><a href="/course/2">requests库</a></li>
        <li class="course-item"><a href="/course/3">XPath教程</a></li>
    </ul>
</div>
"""
tree = etree.HTML(html)

# 2. 使用XPath表达式提取数据
# 提取h1标签的文本内容
title = tree.xpath('//h1[@id="title"]/text()')[0]
print(title)  # 输出:Python爬虫教程

# 提取所有课程名称
course_names = tree.xpath('//li[@class="course-item"]/a/text()')
print(course_names)  # 输出:['基础语法', 'requests库', 'XPath教程']

# 提取所有课程链接
course_links = tree.xpath('//li[@class="course-item"]/a/@href')
print(course_links)  # 输出:['/course/1', '/course/2', '/course/3']
3.2.3 XPath核心语法详解

XPath的语法非常简单,你只需要掌握以下常用表达式即可应对90%的静态网页爬取需求:

表达式 含义
/ 从根节点开始,选取直接子节点(绝对路径)
// 从任意位置开始,选取所有匹配的节点(相对路径,最常用)
. 选取当前节点
.. 选取当前节点的父节点
@属性名 选取指定属性的值
text() 选取节点的文本内容
[@属性名="值"] 匹配具有指定属性和值的节点
[索引] 选取第N个节点(注意:XPath索引从1开始!
contains(@属性名, "值") 匹配属性值包含指定字符串的节点
and 多条件匹配
3.2.4 XPath常用示例
Python 复制代码
# 1. 绝对路径(不推荐,容易因为页面结构变化而失效)
tree.xpath('/html/body/div/h1/text()')

# 2. 相对路径(推荐,更稳定)
tree.xpath('//h1/text()')  # 选取所有h1标签的文本

# 3. 按ID匹配
tree.xpath('//h1[@id="title"]/text()')

# 4. 按类名匹配
tree.xpath('//li[@class="course-item"]/a/text()')

# 5. 按属性包含匹配(当类名有多个时非常有用)
tree.xpath('//div[contains(@class, "container")]/h1/text()')

# 6. 多条件匹配
tree.xpath('//li[@class="course-item" and position()=2]/a/text()')  # 选取第二个li标签

# 7. 提取属性值
tree.xpath('//a/@href')  # 提取所有a标签的href属性
tree.xpath('//img/@src')  # 提取所有img标签的src属性(图片链接)

# 8. 选取父节点
tree.xpath('//a[@href="/course/1"]/../@class')  # 选取a标签的父节点li的class属性
3.2.5 浏览器自动生成XPath

对于复杂的页面结构,你不需要手动编写XPath!浏览器可以帮你自动生成:

  1. 在Elements面板中右键点击你想要提取的元素

  2. 选择"复制" → "复制XPath"

  3. 粘贴到你的代码中即可

注意:自动生成的XPath通常是绝对路径,稳定性较差,建议手动修改为相对路径。

小练习:使用lxml和XPath,从上面的示例HTML中提取出所有li标签的class属性值。

3.3 re模块:正则表达式基础

正则表达式是一种用于匹配字符串的强大工具,在爬虫中主要用于提取HTML中无法用XPath轻松提取的内容(比如电话号码、邮箱地址、JSON数据等)。

3.3.1 基本使用
Python 复制代码
import re

# 1. re.findall():查找所有匹配的字符串(最常用)
text = "我的电话号码是:13812345678,邮箱是:test@example.com"

# 匹配电话号码
phone = re.findall(r'1\d{10}', text)
print(phone)  # 输出:['13812345678']

# 匹配邮箱
email = re.findall(r'\w+@\w+\.\w+', text)
print(email)  # 输出:['test@example.com']

# 2. re.search():查找第一个匹配的字符串
match = re.search(r'1\d{10}', text)
if match:
    print(match.group())  # 输出:13812345678
3.3.2 常用正则符号
符号 含义
. 匹配任意单个字符(除了换行符)
* 匹配前面的字符0次或多次
+ 匹配前面的字符1次或多次
? 匹配前面的字符0次或1次
\d 匹配任意数字
\w 匹配任意字母、数字或下划线
\s 匹配任意空白字符
[] 匹配括号中的任意一个字符
() 分组,提取括号内的内容
小练习:使用正则表达式,从字符串"今天的气温是25℃,明天的气温是28℃"中提取出所有的温度数字。

四、实战案例:从零开始写爬虫

案例1:爬取静态网页的文本信息(新闻标题列表)

目标:爬取"中国新闻网"的国内新闻标题列表。

步骤1:分析网页
  1. 打开中国新闻网国内新闻页面:https://www.chinanews.com.cn/china.shtml

  2. 按F12打开开发者工具,使用箭头工具点击任意一条新闻标题

  3. 观察HTML结构,找到新闻标题所在的标签和属性

  4. 编写XPath表达式提取标题和链接

步骤2:编写代码
Python 复制代码
import requests
from lxml import etree

# 1. 设置请求头,伪装成浏览器
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"
}

# 2. 发送GET请求,获取网页内容
url = "https://www.chinanews.com.cn/china.shtml"
response = requests.get(url, headers=headers)
response.encoding = "utf-8"  # 设置编码,防止乱码

# 3. 解析HTML
tree = etree.HTML(response.text)

# 4. 使用XPath提取新闻标题和链接
# 注意:XPath表达式需要根据实际网页结构调整
news_list = tree.xpath('//div[@class="news_list"]/ul/li/div[@class="dd_bt"]/a')

# 5. 遍历结果,打印信息
for news in news_list:
    title = news.xpath('./text()')[0].strip()  # 提取标题,strip()去除首尾空格
    link = news.xpath('./@href')[0]  # 提取链接
    print(f"标题:{title}")
    print(f"链接:https://www.chinanews.com.cn{link}")
    print("-" * 50)
常见问题和解决方法
  • XPath提取不到数据:检查XPath表达式是否正确,网页结构是否发生了变化

  • 乱码问题 :确保设置了正确的编码(response.encoding = "utf-8"

  • 请求被拒绝:检查User-Agent是否正确,或者尝试添加更多的请求头字段

案例2:爬取静态网页的图片并保存到本地

目标:爬取"pexels"网站的风景图片并保存到本地。

步骤1:分析网页
  1. 打开pexels风景图片页面:https://www.pexels.com/search/landscape/

  2. 按F12打开开发者工具,使用箭头工具点击任意一张图片

  3. 找到图片的src属性(图片链接)

  4. 编写XPath表达式提取所有图片链接

步骤2:编写代码
Python 复制代码
import requests
from lxml import etree
import os

# 1. 创建保存图片的文件夹
if not os.path.exists("images"):
    os.mkdir("images")

# 2. 设置请求头
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"
}

# 3. 发送请求,获取网页内容
url = "https://www.pexels.com/search/landscape/"
response = requests.get(url, headers=headers)

# 4. 解析HTML,提取图片链接
tree = etree.HTML(response.text)
img_urls = tree.xpath('//img[@class="photo-item__img"]/@src')

# 5. 下载并保存图片
for i, img_url in enumerate(img_urls):
    print(f"正在下载第{i+1}张图片:{img_url}")
    try:
        # 发送请求获取图片二进制内容
        img_response = requests.get(img_url, headers=headers, timeout=10)
        # 保存图片
        with open(f"images/{i+1}.jpg", "wb") as f:
            f.write(img_response.content)
        print("下载成功!")
    except Exception as e:
        print(f"下载失败:{e}")
常见问题和解决方法
  • 图片链接是相对路径:需要拼接成完整的URL

  • 图片加载失败:添加异常处理,跳过失败的图片

  • 下载速度慢:可以使用多线程下载(入门阶段不建议)

案例3:爬取需要翻页的多页数据

目标:爬取"豆瓣读书"Top250的书籍信息(书名、作者、评分、简介)。

步骤1:分析翻页规律
  1. 打开豆瓣读书Top250页面:https://book.douban.com/top250

  2. 点击第2页,观察URL变化:https://book.douban.com/top250?start=25

  3. 点击第3页,URL变为:https://book.douban.com/top250?start=50

  4. 规律:每页显示25条数据,start参数从0开始,每次增加25

步骤2:编写代码
Python 复制代码
import requests
from lxml import etree
import time
import csv

# 1. 设置请求头
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"
}

# 2. 创建CSV文件,写入表头
with open("douban_book_top250.csv", "w", newline="", encoding="utf-8-sig") as f:
    writer = csv.writer(f)
    writer.writerow(["排名", "书名", "作者", "评分", "简介"])

# 3. 循环爬取10页数据
for page in range(10):
    start = page * 25
    url = f"https://book.douban.com/top250?start={start}"
    print(f"正在爬取第{page+1}页:{url}")
    
    try:
        # 发送请求
        response = requests.get(url, headers=headers, timeout=10)
        tree = etree.HTML(response.text)
        
        # 提取所有书籍信息
        books = tree.xpath('//tr[@class="item"]')
        
        for i, book in enumerate(books):
            rank = page * 25 + i + 1
            title = book.xpath('.//div[@class="pl2"]/a/@title')[0]
            info = book.xpath('.//p[@class="pl"]/text()')[0].strip()
            rating = book.xpath('.//span[@class="rating_num"]/text()')[0]
            # 有些书籍没有简介,需要处理异常
            try:
                quote = book.xpath('.//span[@class="inq"]/text()')[0]
            except:
                quote = "无"
            
            # 写入CSV文件
            with open("douban_book_top250.csv", "a", newline="", encoding="utf-8-sig") as f:
                writer = csv.writer(f)
                writer.writerow([rank, title, info, rating, quote])
        
        print(f"第{page+1}页爬取完成!")
        # 控制爬取速度,每爬完一页休息2秒
        time.sleep(2)
        
    except Exception as e:
        print(f"第{page+1}页爬取失败:{e}")

print("所有数据爬取完成!")
常见问题和解决方法
  • IP被封禁 :降低爬取频率,增加time.sleep()的时间

  • 数据缺失:添加异常处理,跳过缺失的数据

  • CSV文件乱码 :使用encoding="utf-8-sig"编码,Excel打开不会乱码

五、数据存储:把爬取的数据保存下来

5.1 保存为TXT文件

最简单的存储方式,适合保存纯文本数据。

Python 复制代码
# 写入TXT文件
with open("data.txt", "w", encoding="utf-8") as f:
    f.write("这是第一行数据\n")
    f.write("这是第二行数据\n")

# 追加写入TXT文件
with open("data.txt", "a", encoding="utf-8") as f:
    f.write("这是追加的一行数据\n")

5.2 保存为CSV文件

适合保存表格型数据,可以用Excel直接打开。

Python 复制代码
import csv

# 写入CSV文件
with open("data.csv", "w", newline="", encoding="utf-8-sig") as f:
    writer = csv.writer(f)
    # 写入表头
    writer.writerow(["姓名", "年龄", "城市"])
    # 写入数据
    writer.writerow(["张三", 20, "北京"])
    writer.writerow(["李四", 25, "上海"])

5.3 保存为JSON文件

适合保存结构化数据,方便后续程序读取和处理。

Python 复制代码
import json

data = [
    {"name": "张三", "age": 20, "city": "北京"},
    {"name": "李四", "age": 25, "city": "上海"}
]

# 写入JSON文件
with open("data.json", "w", encoding="utf-8") as f:
    json.dump(data, f, ensure_ascii=False, indent=4)

# 读取JSON文件
with open("data.json", "r", encoding="utf-8") as f:
    data = json.load(f)
    print(data)

六、基础反爬应对措施

网站为了防止被爬虫恶意爬取,会采取各种反爬措施。作为初学者,你只需要掌握以下最基础的应对方法:

6.1 User-Agent伪装

这是最基础也是最重要的反爬应对措施。所有爬虫都必须设置User-Agent,伪装成浏览器。

Python 复制代码
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"
}
response = requests.get(url, headers=headers)

6.2 控制爬取频率

短时间内发送大量请求会给服务器造成过大压力,很容易被封禁IP。可以使用time.sleep()在每次请求之间添加延迟。

Python 复制代码
import time

for url in url_list:
    response = requests.get(url, headers=headers)
    # 每次请求后休息1-3秒
    time.sleep(random.randint(1, 3))

6.3 遇到更复杂反爬时的学习方向

如果遇到了更复杂的反爬措施(比如验证码、登录验证、动态加载数据等),你可以按照以下路线继续学习:

  1. 动态网页爬取:DrissionPage、Selenium、Playwright

  2. 验证码识别:ddddocr、打码平台

  3. 代理IP使用:应对IP封禁

  4. 爬虫框架:Scrapy(提高开发效率)

七、总结与后续学习建议

7.1 爬虫入门核心知识点总结

  1. 爬虫原理:模拟浏览器发送HTTP请求,获取并解析网页数据

  2. 必备工具

    • requests库:发送HTTP请求

    • lxml库 + XPath:解析HTML,提取数据

    • re模块:正则表达式,处理复杂字符串

  3. 核心技能:使用浏览器开发者工具分析网页结构和网络请求

  4. 数据存储:TXT、CSV、JSON三种基本存储方式

  5. 反爬应对:User-Agent伪装、控制爬取频率

7.2 后续学习路线图

  1. 巩固基础:多写几个实战案例,熟练掌握requests和XPath的使用

  2. 进阶学习

    • 学习DrissionPage爬取动态网页

    • 学习Scrapy爬虫框架

    • 学习代理IP、Cookie池、验证码识别等高级反爬技术

  3. 项目实战:找一个自己感兴趣的网站,尝试爬取完整的数据

  4. 拓展学习:学习数据分析和可视化,将爬取的数据转化为有价值的信息

7.3 初学者常见错误和避坑指南

  1. 忘记设置User-Agent:这是最常见的错误,会导致请求被服务器拒绝

  2. 爬取速度太快:容易被封禁IP,一定要控制爬取频率

  3. 不处理异常:网络请求随时可能失败,一定要添加try-except异常处理

  4. XPath写得太复杂:尽量使用相对路径和稳定的属性(如ID)来定位元素

  5. 不遵守robots协议:可能会引发法律纠纷

  6. 直接复制浏览器的XPath:自动生成的XPath通常是绝对路径,稳定性较差

写在最后

爬虫是一门非常实用的技术,它能让你从互联网上获取海量的数据。但请记住,技术本身没有好坏之分,关键在于如何使用它。希望你能遵守法律法规和道德规范,用爬虫技术做有意义的事情。

学习爬虫最好的方法就是多动手实践。不要只看教程,一定要自己动手写代码,遇到问题多思考、多搜索。当你成功爬取第一个网站的数据时,你会感受到爬虫的魅力!

相关推荐
lulu121654407811 小时前
【开发者指南】Gemini 3.5开发入门:从API调用到Agent构建
java·开发语言·人工智能·python·ai编程
沐风。5611 小时前
AI 实战
python
我能坚持多久11 小时前
STL详解——stack以及queue的模拟实现
开发语言·c++·学习
三无推导11 小时前
《OpenHands 安装部署教程:用 Docker 在本地快速跑通开源 AI 编码助手》
人工智能·python·docker·性能优化·开源·github
财经资讯数据_灵砚智能11 小时前
基于全球经济类多源新闻的NLP情感分析与数据可视化(夜间-次晨)2026年5月24日
人工智能·python·信息可视化·自然语言处理·ai编程
深度先生11 小时前
uv:新一代 Python 包管理器,快到离谱
python
不是株11 小时前
RAG
人工智能·python·langchain
Metaphor69211 小时前
使用 Python 将 HTML 转换为 Excel
python·html·excel
Chasing__Dreams11 小时前
大模型应用开发--2--AGENT问题
python