爬虫工程师入门阶段一:基础知识点完全学习文档

🐍 爬虫工程师入门阶段一:基础知识点完全学习文档

欢迎来到爬虫世界!阶段一的目标是让你掌握爬虫最核心的基础知识,能够独立完成简单的静态网页数据抓取。本文档将详细拆解每一个知识点,并配有代码示例和实战练习,帮助你扎实入门。


目录

  1. [Python 基础回顾](#Python 基础回顾)
  2. [HTTP/HTTPS 协议核心](#HTTP/HTTPS 协议核心)
  3. [HTML/CSS 基础与选择器](#HTML/CSS 基础与选择器)
  4. [Requests 库完全指南](#Requests 库完全指南)
  5. [BeautifulSoup 解析 HTML](#BeautifulSoup 解析 HTML)
  6. [数据存储:TXT / CSV / JSON](#数据存储:TXT / CSV / JSON)
  7. 阶段一实战练习题

1. Python 基础回顾

在开始爬虫之前,你需要掌握 Python 最基本的语法和常用操作。以下是你必须熟悉的内容:

1.1 变量与数据类型

  • 数字int(整数)、float(浮点数)
  • 字符串str,常用方法 strip(), split(), replace(), join(), encode()/decode()
  • 列表list,增删改查、切片、遍历
  • 字典dict,键值对操作、遍历
  • 元组tuple,不可变序列
  • 集合set,去重、交集并集

1.2 控制流

  • if / elif / else 条件判断
  • for 循环和 while 循环
  • breakcontinueelse 子句

1.3 函数

  • 定义函数 def
  • 参数(位置参数、默认参数、关键字参数)
  • 返回值 return

1.4 文件操作

  • 打开文件:open(file, mode)
  • 读取:read(), readline(), readlines()
  • 写入:write(), writelines()
  • 使用 with 语句自动关闭文件

1.5 异常处理

  • try / except / finally
  • 捕获特定异常类型

1.6 常用内置模块

  • os:文件和路径操作
  • sys:系统相关参数
  • time:时间处理、休眠
  • random:随机数
  • json:JSON 解析(后面会重点用到)

练习:写一个函数,读取一个文本文件,统计其中每个单词出现的次数,返回字典。


2. HTTP/HTTPS 协议核心

爬虫本质上是模拟浏览器向服务器发送请求并获取响应。理解 HTTP 协议是爬虫的基础。

2.1 什么是 HTTP?

HTTP(HyperText Transfer Protocol)是互联网上应用最广泛的一种网络协议,用于从 Web 服务器传输超文本到本地浏览器。

2.2 URL 结构

一个典型的 URL:https://www.example.com:443/path/to/page?key1=value1&key2=value2#section

  • 协议https://
  • 域名www.example.com
  • 端口:443(HTTPS 默认 443,HTTP 默认 80)
  • 路径/path/to/page
  • 查询参数?key1=value1&key2=value2
  • 片段#section(通常前端使用,不会发送到服务器)

2.3 HTTP 请求方法

  • GET:请求获取资源(最常见)
  • POST:提交数据给服务器(如表单登录)
  • PUT、DELETE、HEAD、OPTIONS 等(了解即可)

2.4 常见请求头(Headers)

请求头是客户端告诉服务器的一些额外信息,爬虫中经常需要伪装它们。

  • User-Agent:标识客户端类型(浏览器、操作系统等)
  • Referer:表示请求是从哪个页面发出的
  • Cookie:携带会话信息
  • Authorization:身份认证
  • Content-Type:POST 请求时,说明发送的数据格式(如 application/json

2.5 HTTP 响应状态码

服务器返回的状态码表示请求结果,常见的有:

  • 2xx 成功
    • 200 OK:请求成功
  • 3xx 重定向
    • 301 Moved Permanently:永久重定向
    • 302 Found:临时重定向
  • 4xx 客户端错误
    • 403 Forbidden:禁止访问
    • 404 Not Found:资源不存在
  • 5xx 服务器错误
    • 500 Internal Server Error:服务器内部错误

2.6 响应内容

服务器返回的响应体通常是 HTML、JSON、图片、文件等。爬虫主要解析 HTML 或 JSON。

2.7 HTTPS

HTTPS 是 HTTP 的安全版本,数据经过 SSL/TLS 加密。爬虫处理 HTTPS 与 HTTP 基本一致,requests 库会自动处理证书验证。


3. HTML/CSS 基础与选择器

爬虫抓取的数据通常隐藏在 HTML 结构中,因此你需要能看懂 HTML,并能用选择器定位到目标元素。

3.1 HTML 基础

HTML 由标签和属性组成,常见结构:

html 复制代码
<!DOCTYPE html>
<html>
<head>
    <title>页面标题</title>
</head>
<body>
    <div id="content" class="wrapper">
        <h1>文章标题</h1>
        <p class="intro">这是一段介绍。</p>
        <ul>
            <li>列表项1</li>
            <li>列表项2</li>
        </ul>
    </div>
</body>
</html>

3.2 常用标签

  • <div>:块级容器
  • <p>:段落
  • <a>:超链接
  • <img>:图片
  • <ul> / <li>:无序列表
  • <table> / <tr> / <td>:表格
  • <span>:内联容器
  • <h1> ~ <h6>:标题

3.3 属性

  • id:唯一标识符
  • class:类名(可重复,用于 CSS 样式)
  • href:链接地址
  • src:图片或脚本地址
  • title:提示文本

3.4 CSS 选择器(重点)

CSS 选择器用于定位元素,在爬虫中常用 BeautifulSoup 的 select() 方法或 lxmlxpath。这里先介绍最常用的几种:

选择器 示例 说明
标签选择器 div 所有 <div> 元素
类选择器 .intro class="intro" 的元素
ID 选择器 #content id="content" 的元素
属性选择器 [href] 带有 href 属性的元素
后代选择器 div p <div> 内的所有 <p>
子元素选择器 div > p <div> 的直接子元素 <p>
并列选择器 div.wrapper <div class="wrapper">

练习:用上述选择器选出示例 HTML 中的:

  • 所有 <li> 元素
  • class="intro" 的段落
  • id="content"div

4. Requests 库完全指南

requests 是 Python 中最优雅的 HTTP 库,几乎成为了爬虫的事实标准。

4.1 安装

bash 复制代码
pip install requests

4.2 发送 GET 请求

最简单的用法:

python 复制代码
import requests

url = 'https://api.github.com'
response = requests.get(url)
print(response.text)  # 打印响应内容(字符串)

4.3 添加请求头

很多网站需要你伪装成浏览器,否则会拒绝访问。常见的请求头有 User-Agent

python 复制代码
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
}
response = requests.get(url, headers=headers)

4.4 传递 URL 参数

GET 请求的参数可以通过 params 参数传递,它会自动编码并附加到 URL 后。

python 复制代码
params = {'key1': 'value1', 'key2': 'value2'}
response = requests.get('https://httpbin.org/get', params=params)
print(response.url)  # 输出:https://httpbin.org/get?key1=value1&key2=value2

4.5 发送 POST 请求

POST 通常用于提交表单或 JSON 数据。

python 复制代码
# 表单形式(Content-Type: application/x-www-form-urlencoded)
data = {'username': 'user', 'password': 'pass'}
response = requests.post('https://httpbin.org/post', data=data)

# JSON 形式(Content-Type: application/json)
import json
json_data = {'key': 'value'}
response = requests.post('https://httpbin.org/post', json=json_data)

4.6 响应对象

response 对象包含服务器返回的所有信息:

  • response.status_code:状态码(如 200)
  • response.headers:响应头(字典形式)
  • response.text:响应内容(字符串,自动解码)
  • response.content:响应内容(字节形式)
  • response.json():如果响应是 JSON,可直接解析为字典
  • response.encoding:查看或设置编码
  • response.url:最终请求的 URL(可能经历重定向)

4.7 会话对象(Session)

如果你需要保持某些参数(如 Cookie)跨请求,可以使用 Session 对象。它会在多次请求中自动保存 Cookie。

python 复制代码
s = requests.Session()
s.get('https://httpbin.org/cookies/set/sessioncookie/123456789')
r = s.get('https://httpbin.org/cookies')
print(r.text)  # 会看到设置的 Cookie

4.8 超时设置

为防止请求卡死,建议设置超时时间:

python 复制代码
response = requests.get(url, timeout=3)  # 3秒后超时

4.9 代理

如果你需要使用代理,可以通过 proxies 参数:

python 复制代码
proxies = {
    'http': 'http://127.0.0.1:8888',
    'https': 'http://127.0.0.1:8888',
}
response = requests.get(url, proxies=proxies)

4.10 异常处理

网络请求可能出错,建议捕获异常:

python 复制代码
from requests.exceptions import RequestException

try:
    response = requests.get(url, timeout=3)
    response.raise_for_status()  # 如果状态码不是200,抛出HTTPError
except RequestException as e:
    print(f'请求出错:{e}')

练习:使用 requests 获取百度首页的 HTML,打印状态码和前 500 个字符。


5. BeautifulSoup 解析 HTML

获取到 HTML 后,我们需要从中提取数据。BeautifulSoup 是一个强大易用的解析库。

5.1 安装

bash 复制代码
pip install beautifulsoup4 lxml

lxml 是解析器,比 Python 内置的解析器更快。

5.2 基本用法

python 复制代码
from bs4 import BeautifulSoup

html_doc = """
<html><head><title>The Dormouse's story</title></head>
<body>
<p class="title"><b>The Dormouse's story</b></p>
<p class="story">Once upon a time there were three little sisters; and their names were
<a href="http://example.com/elsie" class="sister" id="link1">Elsie</a>,
<a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and
<a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>;
and they lived at the bottom of a well.</p>
<p class="story">...</p>
"""

soup = BeautifulSoup(html_doc, 'lxml')

5.3 查找元素的方法

5.3.1 find()find_all()
  • find(name, attrs, recursive, string, **kwargs):返回第一个匹配的元素
  • find_all(name, attrs, recursive, string, limit, **kwargs):返回所有匹配的元素列表

示例:

python 复制代码
# 查找第一个 <p> 标签
p = soup.find('p')

# 查找所有 <a> 标签
all_links = soup.find_all('a')

# 查找 class="sister" 的标签
sisters = soup.find_all(class_='sister')  # 注意 class 后面加下划线

# 查找 id="link1" 的标签
link1 = soup.find(id='link1')
5.3.2 select() 方法(使用 CSS 选择器)
python 复制代码
# 选择所有 <a> 标签
links = soup.select('a')

# 选择 class="sister" 的标签
sisters = soup.select('.sister')

# 选择 id="link1" 的标签
link1 = soup.select('#link1')

# 选择 <p> 标签内的 <a> 标签
p_links = soup.select('p a')

5.4 获取标签内容

  • tag.name:标签名
  • tag.texttag.get_text():获取标签内的文本内容(包含子标签文本)
  • tag.string:如果标签内只有文本,返回该文本;如果有子标签,返回 None
  • tag.attrs:获取所有属性组成的字典
  • tag.get('属性名'):获取指定属性的值

示例:

python 复制代码
for a in soup.find_all('a'):
    print(a.text)          # 链接文字
    print(a.get('href'))   # 链接地址
    print(a['href'])       # 另一种方式(如果属性不存在会报错)

5.5 实战:提取豆瓣电影标题

python 复制代码
import requests
from bs4 import BeautifulSoup

url = 'https://movie.douban.com/top250'
headers = {'User-Agent': 'Mozilla/5.0'}
response = requests.get(url, headers=headers)
soup = BeautifulSoup(response.text, 'lxml')

# 每部电影信息在 <li> 标签中,class="item"
movies = soup.select('.item')
for movie in movies:
    title = movie.find('span', class_='title').text  # 电影名
    rating = movie.find('span', class_='rating_num').text  # 评分
    print(title, rating)

练习:抓取一个简单的静态页面(比如 https://books.toscrape.com/),提取所有书籍的标题和价格。


6. 数据存储:TXT / CSV / JSON

爬到的数据需要保存下来,最常用的格式是 CSV 和 JSON。

6.1 保存为 TXT

直接用文件写入即可:

python 复制代码
with open('data.txt', 'w', encoding='utf-8') as f:
    f.write('要保存的文本')

6.2 保存为 CSV

CSV(逗号分隔值)可以用 Python 内置的 csv 模块,也可以用 pandas(但阶段一先不用)。

python 复制代码
import csv

# 准备数据,列表的列表
data = [
    ['电影名', '评分'],
    ['肖申克的救赎', '9.7'],
    ['霸王别姬', '9.6']
]

with open('movies.csv', 'w', newline='', encoding='utf-8-sig') as f:
    writer = csv.writer(f)
    writer.writerows(data)

encoding='utf-8-sig' 可以让 Excel 正确打开中文 CSV。

6.3 保存为 JSON

JSON 是轻量级数据交换格式,非常适合保存结构化数据。

python 复制代码
import json

data = [
    {'title': '肖申克的救赎', 'rating': 9.7},
    {'title': '霸王别姬', 'rating': 9.6}
]

with open('movies.json', 'w', encoding='utf-8') as f:
    json.dump(data, f, ensure_ascii=False, indent=2)
  • ensure_ascii=False 允许中文正常显示
  • indent=2 美化输出

练习:将豆瓣 Top250 的前 10 部电影信息(排名、片名、评分)保存为 CSV 文件。


7. 阶段一实战练习题

为了检验你是否掌握了以上所有知识点,请独立完成以下两个题目。每个题目都附有解题思路,先自己尝试,实在困难再参考提示。

练习一:爬取豆瓣电影 Top250

  • 目标https://movie.douban.com/top250
  • 数据字段:电影排名(1-250)、中文片名、导演、上映年份、评分、评价人数
  • 要求:分页爬取(共 10 页),保存为 CSV 文件。
  • 提示
    1. 第一页 URL:https://movie.douban.com/top250?start=0,第二页 start=25,以此类推。
    2. 需要设置 User-Agent 请求头,否则会返回 418。
    3. 使用 BeautifulSoup 解析,每个电影信息在一个 <li> 标签中,class="item"
    4. 电影排名在 <em> 标签中。
    5. 片名在 span 标签 class="title" 中(注意可能有英文名干扰,取第一个)。
    6. 导演等其他信息在 <p class=""> 中,需要正则或 split 处理。
    7. 评分在 span 标签 class="rating_num" 中。
    8. 评价人数在 <div class="star"> 内的最后一个 <span> 中,需提取数字。

解题思路框架

python 复制代码
import requests
from bs4 import BeautifulSoup
import csv
import time

def fetch_page(start):
    url = f'https://movie.douban.com/top250?start={start}'
    headers = {'User-Agent': 'Mozilla/5.0'}
    resp = requests.get(url, headers=headers)
    soup = BeautifulSoup(resp.text, 'lxml')
    movies = soup.select('.item')
    page_data = []
    for movie in movies:
        rank = movie.find('em').text
        title = movie.find('span', class_='title').text
        # 提取导演、年份等
        info = movie.find('p', class_='').text.strip()
        # 用正则或字符串分割提取导演和年份
        # ...
        rating = movie.find('span', class_='rating_num').text
        # 提取评价人数
        star = movie.find('div', class_='star')
        num = star.find_all('span')[-1].text[:-3]  # 去掉"人评价"
        page_data.append([rank, title, director, year, rating, num])
    return page_data

all_data = [['排名', '片名', '导演', '年份', '评分', '评价人数']]
for i in range(0, 250, 25):
    all_data.extend(fetch_page(i))
    time.sleep(2)  # 礼貌延时

with open('douban_top250.csv', 'w', newline='', encoding='utf-8-sig') as f:
    writer = csv.writer(f)
    writer.writerows(all_data)

练习二:爬取当当网图书列表

  • 目标http://category.dangdang.com/cp01.01.02.00.00.00.html(计算机/网络类)
  • 数据:商品名称、价格、作者、出版社、评论数
  • 要求:爬取至少 3 个分类(如计算机、小说、童书),每个分类前 5 页,保存为 JSON 文件。
  • 提示
    1. 观察 URL 规律,不同分类对应不同 ID,页数参数 pg=2 表示第 2 页。
    2. 当当网有简单的反爬,需要设置 User-Agent,并适当延时。
    3. 每个商品在 <li> 标签中,class 可能为 line1 或类似,可以用 select('.line1') 选择。
    4. 价格通常在一个带有 price 类的标签中。
    5. 作者、出版社在 <p class="search_book_author"> 中,用 <span> 分割。
    6. 评论数在 <a> 标签内,可能包含 "条评论",需提取数字。

解题思路框架

python 复制代码
import requests
from bs4 import BeautifulSoup
import json
import time

def fetch_category(category_url, category_name, pages=5):
    all_books = []
    for page in range(1, pages+1):
        url = f'{category_url}&page={page}'  # 根据实际URL调整
        headers = {'User-Agent': 'Mozilla/5.0'}
        resp = requests.get(url, headers=headers)
        soup = BeautifulSoup(resp.text, 'lxml')
        items = soup.select('.line1')  # 商品项选择器
        for item in items:
            name = item.find('a', class_='pic').get('title')  # 商品名
            price = item.find('span', class_='price_n').text  # 价格
            # 提取作者、出版社
            author_info = item.find('p', class_='search_book_author').text.strip()
            # 处理字符串...
            comment = item.find('a', class_='red').text.strip('条评论')
            all_books.append({
                'name': name,
                'price': price,
                'author': author,
                'publisher': publisher,
                'comment': comment
            })
        time.sleep(2)
    return {category_name: all_books}

# 定义要爬的分类URL和名称
categories = {
    '计算机': 'http://category.dangdang.com/cp01.01.02.00.00.00.html',
    '小说': 'http://category.dangdang.com/cp01.01.01.00.00.00.html',
    '童书': 'http://category.dangdang.com/cp01.00.00.00.00.00.html?cpath=01.00.00.00.00.00'
}
result = {}
for name, url in categories.items():
    result[name] = fetch_category(url, name)

with open('dangdang.json', 'w', encoding='utf-8') as f:
    json.dump(result, f, ensure_ascii=False, indent=2)

恭喜你完成了阶段一的学习!现在你已经具备了编写基础爬虫的能力。接下来可以进入阶段二,学习如何处理登录、会话和更复杂的反爬措施。记住:多动手实践是进步最快的方法。如果在练习题中遇到问题,欢迎随时查阅文档或搜索引擎。加油!

相关推荐
三品吉他手会点灯1 小时前
C语言学习笔记 - 20.C编程预备计算机专业知识 - 变量为什么必须的初始化【重点】
c语言·笔记·学习
zh1570231 小时前
JavaScript中WorkerThreads解决服务端计算瓶颈
jvm·数据库·python
sakiko_1 小时前
UIKit学习笔记1-创建项目(使用UIKit)、使用组件
笔记·学习
生信碱移1 小时前
PACells:这个方法可以鉴定疾病/预后相关的重要细胞亚群,作者提供的代码流程可以学习起来了,甚至兼容转录组与 ATAC 两种数据类型!
人工智能·学习·算法·机器学习·数据挖掘·数据分析·r语言
玩嵌入式的菜鸡2 小时前
网页访问单片机设备---基于mqtt
前端·javascript·css
蜡台2 小时前
Python包管理工具pip完全指南-----2
linux·windows·python
Mr.朱鹏2 小时前
【Python 进阶 | 第四篇】Psycopg3 + Flask 实现 PostgreSQL CRUD 全流程:从连接池到RESTful接口
python·postgresql·flask·virtualenv·fastapi·pip·tornado
2401_871492852 小时前
Vue.js监听器watch利用回调函数处理级联下拉框数据联动
jvm·数据库·python
FreakStudio2 小时前
亲测可用!可本地部署的 MicroPython 开源仿真器
python·单片机·嵌入式·面向对象·并行计算·电子diy·电子计算机
Dxy12393102163 小时前
HTML中的Canvas入门:从零开始绘制图形世界
html