程序语言:Python
开发平台:PyCharm【2017版本以上】
前言须知
本文目的:实现基于 PyCharm 开发平台的对 TB商品信息 进行爬取数据的行为。
爬虫对象:TB商品-凹凸曼
必须掌握:Python + HTML 基础知识
其他重要声明:本文章仅用于学习与分享,任何从事用于非法行为所造成的后果请自负。
分析:爬取流程 与 第三方依赖库 剖析
如上图所示,完整的 Python 爬取流程。根据上述流程表反馈信息,至少有 3个 阶段的内容需程序实现。即 网页数据请求、响应数据解析、数据信息存储 三个板块。
-
网页数据请求:模拟浏览器请求服务器终端数据,任何访问网络地址的行为,其远端服务器将返回数据信息。
网页数据的存储位置:存储于网页的 HTML 源码中。 -
响应数据解析:并非访问即可获取数据。存在远端服务器宕机、网络波动、远端防火墙禁止访问等因素阻碍获取数据内容。能否获取到信息决定后续操作是否可执行。
-
数据信息存储:记录网页面的数据信息,用于二次清洗筛选重要数据后的内容存储。
综合上述分析,为可总结使用到以下至少3个 Python 库。
requests
库:主要模拟浏览器访问网络地址的方式。【重要】re
库:主要用于访问成功后,对数据信息的二次筛查与清洗工作。【重要】time
库:主要模拟计时器,在部分情况下有助于提高访问成功率。
存在被服务器配备有限制访问频率的IP监禁机制,使用该库可有效减少单位时间的访问频率。
实践:模拟对TB的数据爬取
准备工作:引入第三方依赖库
import requests # 重要
import re # 重要
请求服务:解析服务器响应结果
# 定义获取HTML内容的方法
def getHtmlText(URL):
try:
r = requests.get(url=URL, timeout=30)
# 检查响应
r.raise_for_status()
print("...网页响应成功 200")
# 检查是否乱码
if r.encoding == 'utf-8':
print("...网页源码为utf-8 无乱码")
else:
print(r.encoding)
return
# time.sleep(2)
print("...获取HTML页面完成")
return r.text
except:
return ""
requests.get()
:请求数据服务器的方法。
参数timeout
:表示连接超时设定时间后将不再进行请求。raise_for_status()
:检查访问是否成功的依据,默认情况下,返回 200 成功请求信息。若失败则返回其他信息。此处应建议新增r.raise_for_status() == 200
的判断最佳。encoding
:是计算机识别编码格式的依据,根据不同地区用户的语言所制定的本地化文字数据库。
例如国内通用的是 UTF-8(简体中文)。若为其他编码格式,乱码文字将不利于我们进行解析。try...except
:异常情况的多种处理方法。except
不唯一。
解析数据:筛选与清洗关键数据
# 定义解析数据的方法
def fillUnivList(uList, html):
try:
names = re.findall(r'\<span class=\"title\" title=.*?\>', html)
prices = re.findall(r'\<strong\>[\d\.]*<\/strong\>', html)
print("...页面数据解析完成")
# time.sleep(2)
print("...开始数据清洗")
for i in range(len(names)):
name = names[i].split('"')[3] # 以"为切割标识,取第4段
price = re.split(">|<", prices[i])[2] # 以>或<为切割标识。取第2段
uList.append([name, price])
except:
print("解析出错")
- 局部参数
uList
:数组类型。主要用于存储网页响应数据的存储。 - 局部参数
html
:网页源码信息。等效于GetHtmlText(URL)
。 findall(匹配规则, 匹配内容)
:匹配查找方法。其中匹配规则使用 正则表达式进行。具体的匹配规则参考网页源码信息进行。如下图所示,获取 正版奥特曼初代赛文… 的TB标价数据【¥65.00】(见文章顶端),通过 右键该数据 - 检查 定位到该数据在源码中的位置。并按照此内容段配置解析规则。Splite(匹配规则, 匹配内容)
:分割内容方法。用于剔除或筛选精选内容。try...except
:同前文描述。
存储信息:写入 TXT 文本文件
# 定义格式化输出的方法
def printUnivList(uList, Path):
# 读写
with open(Path, 'a', encoding="utf-8") as f:
f.write("商品\t价格\n")
for i in range(len(uList)):
u = uList[i]
f.write(u[0] + "\t") # 写入商品名称
f.write(u[1] + "\n") # 写入商品价格
f.close() # 关闭文件,避免长时间占用系统资源
print("成功存储到文件")
- 局部参数
uList
:解析与清洗后的商品数据内容。 - 局部参数
Path
:TXT 文本文件存储地址。
测试运行:检查数据获取是否成功
def main():
uinfo = [] # 定义用于存储信息的数组
good = "奥特曼" # 定义需要搜索的商品名称
page = 1 # 设置浏览页面数——因为商品数量众多,这里仅设置浏览1页的所有商品信息
path = "D:\\" + good + ".txt" # 设置数据存储路径
# 遍历要浏览的商品页数
for i in range(page):
# 淘宝的商品地址,通过解析URL地址,其内容格式可简化为 【淘宝地址-搜索物品名称-当前页数】
URL = "https://re.taobao.com/search_ou?keyword=" + good + "&page=" + str(i)
html = getHtmlText(URL) # 调用方法
# time.sleep(2)
fillUnivList(uinfo, html) # 调用方法
# time.sleep(2)
print("共搜索了", len(uinfo), "条结果")
# time.sleep(2)
printUnivList(uinfo, path) # 调用方法
if __name__ == "__main__":
main()
根据 请求服务、解析数据、存储信息 定义的方法内容,声明与之匹配的参数变量。如上图所示。大致有以下声明信息:
uinfo
:存储信息good
:商品信息名称。该商品信息名称参考 页面链接地址 的命名规则进行。page
:页面码。商品页面不局限于仅一页。该参考同样依赖于 页面链接地址 的命名规则进行。path
:本地计算机文件存储地址。
检查数据:控制台Debug结果 与 文本文件内容
其他:关于正文中的英文解释
应平台要求,可解读为中文拼音首字母。