Python 爬虫实战:解析并下载百度文库内容
前言
本文介绍如何使用 Python 的 requests 库和正则表达式解析百度文库页面,提取文档标题、页码信息及文本内容,并将结果保存为 doc 文件。同时提供图片数据的提取与下载方法,包含请求头设置、参数解析及去重处理等关键步骤。
本教程旨在帮助开发者理解网页数据抓取的基本流程,包括 HTML 解析、API 接口调用以及文件存储操作。请注意,爬虫技术应仅用于合法合规的学习与研究目的,请勿侵犯版权或用于商业牟利。
环境准备
在开始之前,请确保您的开发环境中已安装 Python 3.x 版本,并通过 pip 安装了必要的依赖库:
pip install requests
代码中使用了标准库 os, re, json, urllib.request,无需额外安装。
核心类设计
我们定义了一个名为 BaiduWk 的类来封装所有爬虫逻辑。该类主要包含以下功能模块:
- 初始化:设置 Session 对象以维持会话状态,配置 User-Agent 模拟浏览器请求。
- HTML 获取:发送 GET 请求获取网页源代码。
- 数据解析:使用正则表达式从源码中提取标题、文档 ID、页码范围等关键参数。
- 文本提取:通过分页请求获取文档 XML 结构中的文本内容。
- 图片下载:解析图片 API 接口,逐页下载文档中的图片资源。
- 文件保存:将提取的文本保存为 .doc 文件,图片保存为 .jpg 格式。
- 去重处理:对保存的文件进行简单的行级去重。
详细代码实现
以下是完整的 Python 脚本代码,包含了上述所有功能的实现细节。
import os
import re
import json
import requests
from urllib.request import urlretrieve
class BaiduWk:
def __init__(self):
self.list_info = []
self.session = requests.session()
# 设置 User-Agent 模拟移动端浏览器,降低被反爬识别的风险
self.headers = {
'User-Agent': 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 '
'(KHTML, like Gecko) Chrome/80.0.3987.87 Mobile Safari/537.36'
}
# 获取网页源代码的数据
():
:
response = .session.get(start_url, headers=.headers)
response.encoding = response.apparent_encoding
response.text
Exception e:
()
():
re_title = re.findall(, data)
title = re_title[] re_title re.findall(, data)[]
params = {
: re.findall(, data)[],
: re.findall(, data)[],
: re.findall(, data)[],
: re.findall(, data)[],
: re.findall(, data)[],
: re.findall(, data)[], }
page_range = re.findall(, data)
params, page_range, title
():
pages = (page_range) +
url =
i (, pages):
()
params[] = i
params[] = page_range[i - ]
response = .session.get(url, params=params).text
response
():
pages =
data response:
a = data[:-]
text =
d = json.loads(a)
j d[]:
c j[]:
text +=
c2 c[]:
:
text += c2[] +
:
text +=
pages +=
.list_info.append(text)
():
os.makedirs(, exist_ok=)
(path, , encoding=) f:
f.writelines(.list_info)
():
()
r = .session.get(start_url)
r.encoding = r.apparent_encoding
title = re.findall(, r.text)[]
(title)
docId = re.findall(, r.text)[]
totalPageNum = re.findall(, r.text)[]
totalPageNum = (totalPageNum) +
totalPageNum, title, docId
():
pn (, totalPageNum):
params = {: docId, : pn, : , : , }
api_url =
r = .session.get(api_url, params=params, headers=.headers)
src = r.json()[].get()
os.makedirs(title, exist_ok=)
path = title + + (pn) +
urlretrieve(src, path)
()
():
word_set = ()
(path, , encoding=) f:
each_line f:
word_set.append(each_line)
result = ((word_set))
result.sort(key=word_set.index)
(path, , encoding=) f:
f.writelines(result)
()
():
()
start_url = ()
()
start_url = re.sub(, , start_url)
html = .get_html(start_url)
html:
()
param, ranges, title = .parse_html(html)
()
path = + title +
response = .words_data(param, ranges)
.get_words(response)
.save_info(title, path)
.set_word(path)
()
()
():
()
start_url = ()
()
totalPageNum, title, docId = .get_img(start_url)
.download_img(totalPageNum, title, docId)
()
()
__name__ == :
wk = BaiduWk()
wk.run_word()


