Python爬虫学习记录—— BooksToScrape分页爬取与图片下载

前面是踩坑和总结,完整代码在最后

目标网站为:

https://books.toscrape.com/

主要内容

  • 分页爬取
  • URL拼接
  • CSV数据存储
  • CSV读取
  • 图片下载
  • 常见编码错误处理

一、分页爬取的核心思想

直接写只能获取首页数据:

python 复制代码
url = "https://books.toscrape.com/"

res = requests.get(url)

但网站实际上有50页数据。

分页爬取的本质:

text 复制代码
请求当前页
    ↓
解析数据
    ↓
找到下一页链接
    ↓
拼接URL
    ↓
继续请求

因此最终采用:

python 复制代码
while url:

    # 请求页面

    # 解析数据

    # 获取下一页

    # 更新url

二、不要手动拼接URL

这是我最开始写法:

python 复制代码
next_url = url + next_href

例如:

python 复制代码
base_url = "https://books.toscrape.com/"
next_href = "page-3.html"

得到:

python 复制代码
https://books.toscrape.com/page-3.html

这是错误的。

因为当前页面实际上位于:

python 复制代码
https://books.toscrape.com/catalogue/page-2.html

正确地址应该是:

python 复制代码
https://books.toscrape.com/catalogue/page-3.html

解决方案:

python 复制代码
from urllib.parse import urljoin

next_url = urljoin(url, next_href)

以后遇到:

python 复制代码
../
./
/path

等相对路径时都能自动处理。


三、next按钮不存在时的错误

最开始写法:

python 复制代码
next_href = soup.find(
    "li",
    class_="next"
).find("a")["href"]

当最后一页没有next按钮时:

python 复制代码
soup.find("li", class_="next")

返回:

python 复制代码
None

程序报错:

python 复制代码
AttributeError:
'NoneType' object has no attribute 'find'

正确写法:

python 复制代码
next_li = soup.find(
    "li",
    class_="next"
)

if next_li is None:
    break

next_href = next_li.find("a")["href"]

四、CSV写入位置问题

错误写法:

python 复制代码
while url:
    with open(
        "books.csv",
        "w"
    ) as f:

        writer.writerow(...)

问题:

每次循环都会重新创建文件。

结果:

text 复制代码
第一页数据被覆盖
第二页数据被覆盖
第三页数据被覆盖
...

最后只剩最后一页。

正确写法:

python 复制代码
with open(
    "books.csv",
    "w",
    newline="",
    encoding="utf-8-sig"
) as f:

    writer = csv.writer(f)

    writer.writerow(
        ["书名","价格","库存","封面"]
    )

    while url:

        writer.writerow(...)

文件只打开一次。


五、CSV编码问题

保存时:

python 复制代码
with open(
    "books.csv",
    "w",
    encoding="utf-8-sig"
)

从csv文件读取内容不要忘记指定编码:

python 复制代码
with open(
    "books.csv",
    "r"
)

导致:

text 复制代码
UnicodeDecodeError

原因:

Windows默认使用GBK读取。

而文件实际编码:

text 复制代码
utf-8-sig

解决:

python 复制代码
with open(
    "books.csv",
    "r",
    encoding="utf-8-sig"
)

读写编码必须一致。


六、enumerate的使用

python 复制代码
for i, item in enumerate(
    data,
    start=1
):
    pass

优点:

  • 代码更简洁
  • 自动计数
  • 可指定起始值

例如:

python 复制代码
for i, item in enumerate(
    reader,
    start=1
):

得到:

text 复制代码
1
2
3
...

七、下载图片

读取CSV中的图片地址:

python 复制代码
reader = csv.DictReader(f)

for row in reader:

    img_url = row["封面"]

下载:

python 复制代码
res = requests.get(
    img_url,
    headers=headers,
    proxies=proxy,
    timeout=10
)

保存:

python 复制代码
with open(
    filename,
    "wb"
) as file:

    file.write(res.content)

注意:

python 复制代码
wb

表示二进制写入。

图片、视频等文件都要使用:

python 复制代码
wb

八、限制下载前10张图片

实现:

python 复制代码
for i, row in enumerate(
    reader,
    start=1
):

    if i > 10:
        break

只下载:

text 复制代码
image_1.png
image_2.png
...
image_10.png

用于测试非常方便。


九、本次项目最终结构

text 复制代码
请求首页
    ↓
解析书籍数据
    ↓
写入CSV
    ↓
寻找下一页
    ↓
翻页
    ↓
保存全部数据
    ↓
读取CSV
    ↓
下载图片

已经完成:

✅ Requests基础使用

✅ BeautifulSoup解析

✅ 分页爬取

✅ URL拼接

✅ CSV存储

✅ CSV读取

✅ 图片下载


十、完整代码

python 复制代码
import requests
from urllib.parse import urljoin
from bs4 import BeautifulSoup
import csv
import os

url = "https://books.toscrape.com/"

#代理,端口改成自己的
proxy = {
    "http":"http://127.0.0.1:7892",
    "https":"http://127.0.0.1:7892"
}

headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36",
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
    "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8",
    "Accept-Encoding": "gzip, deflate, br",
    "Connection": "keep-alive"
}

def get_books():
    global url
    num = 0

    with open("book_1.csv","w",newline="",encoding="utf-8-sig") as f:
            writer = csv.writer(f)

            writer.writerow(["书名","价格","库存","封面"])    

            while url:
                num+=1
                res = requests.get(url,proxies=proxy,headers=headers,timeout=10)
                soup = BeautifulSoup(res.text,"html.parser")

                #解析书籍
                articles = soup.find_all("article",class_="product_pod")
                for article in articles:
                    title = article.find("h3").find("a")["title"]
                    price = article.find("p",class_="price_color").text.strip()
                    instock = article.find("p",class_="instock availability").text.strip()
                    img_url = urljoin(url,article.find("img")["src"])
                
                    writer.writerow([title,price,instock,img_url])
                print(f"当前第{num}页数据写入完成")
                
                #找next,没有直接退出
                next_li = soup.find("li",class_="next")

                if next_li is None:
                    print("爬取完成")
                    break
                
                next_url = next_li.find("a")["href"]

                url = urljoin(url,next_url)


#保存图片
def save_image():
    makedir = "down"
    os.makedirs(makedir,exist_ok=True)

    with open("book_1.csv","r",encoding="utf-8-sig") as f:
        reader = csv.DictReader(f)

        for i,read in enumerate(reader,start=1):

            img_url = read["封面"]

            res = requests.get(img_url,headers=headers,proxies=proxy,timeout=10)

            if i>=10 :
                print("保存成功")
                break
            filename = os.path.join(makedir,f"image_{i}.png")

            with open(filename,"wb") as file:
                file.write(res.content)
             
            
if __name__ == "__main__":
    get_books()
    save_image()
相关推荐
小白学大数据1 小时前
如何自动追踪 eBay 售价?Python 爬虫实战解析
开发语言·人工智能·爬虫·python
ziyue75751 小时前
python进行磁盘文件迁移,不影响软件使用
开发语言·数据库·python
abcy0712131 小时前
Python与Hadoop HDFS进行异步文件上传
python
爱和冰阔落2 小时前
【Python基础】从变量到面向对象:打通 Python 入门核心语法
开发语言·python
财经资讯数据_灵砚智能2 小时前
基于全球经济类多源新闻的NLP情感分析与数据可视化(夜间-次晨)2026年6月7日
大数据·人工智能·python·ai·信息可视化·自然语言处理·灵砚智能
qq3621967052 小时前
AI Crawler深度解析:GPTBot/PerplexityBot/ClaudeBot爬取行为分析与优化
人工智能·爬虫
遇事不決洛必達2 小时前
【爬虫随笔】深入理解 HTTP/HTTPS 协议、接口交互与会话机制
爬虫·网络协议·http·https·session
星川皆无恙2 小时前
Python豆瓣电影数据分析可视化系统:爬虫采集+数据清洗+可视化大屏完整项目
人工智能·爬虫·python·数据分析
ttwuai2 小时前
XYGo Admin 扩展开发:WebSocket 事件注册与实时推送实战
python·websocket·网络协议·golang·后台框架