本文讲解 Python 爬虫实战案例:抓取百度贴吧(https://tieba.baidu.com/)页面,比如 Python爬虫吧、编程吧,只抓取贴吧的前 5 个页面即可。今天一个毕业学生问到一个问题:不清楚编写爬虫的步骤,不知道如何下手,故简单的给该学生简单总结了一下编写步骤,有了编写步骤,在以后编写爬虫按步骤来,兴许会有事半功倍的效果,本文我们将使用面向对象的编程方法来编写程序。注意,本文只简单做步骤编写,不做数据的分析。步骤如下
接下来寻找要爬取页面的 URL 规律,搜索“Python爬虫”后,此时贴吧第一页的的 url 如下所示:
https://tieba.baidu.com/f?ie=utf-8&kw=python爬虫&fr=search
点击第二页,其 url 信息如下:
https://tieba.baidu.com/f?kw=python爬虫&ie=utf-8&pn=50
点击第三页,url 信息如下:
https://tieba.baidu.com/f?kw=python爬虫&ie=utf-8&pn=100
重新点击第一页,url 信息如下:
https://tieba.baidu.com/f?kw=python爬虫&ie=utf-8&pn=0
如果还不确定,您可以继续多浏览几页。最后您发现 url 具有两个查询参数,分别是 kw 和 pn,并且 pn 参数具有规律性,如下所示:
第n页:pn=(n-1)*50
#参数params
pn=(page-1)*50
params={
'kw':name,
'pn':str(pn)
}
url 地址可以简写为:
https://tieba.baidu.com/f?kw=python爬虫&pn=450
以面向对象方法编写爬虫程序时,思路简单、逻辑清楚,非常容易理解,我们可以按照以下步骤进行编写:
请求函数最终的结果是返回一个 HTML 对象,以方便后续的函数调用它。
解析函数用来解析 HTML 页面,常用的解析模块有正则解析模块、bs4 解析模块。通过分析页面,提取出所需的数据,在后续内容会做详细介绍。
该函数负责将抓取下来的数据保至数据库中,比如 MySQL、MongoDB 等,或者将其保存为文件格式,比如 csv、txt、excel 等。
入口函数充当整个爬虫程序的桥梁,通过调用不同的功能函数,实现数据的最终抓取。入口函数的主要任务是组织数据,比如要搜索的贴吧名、编码 url 参数、拼接 url 地址、定义文件保存路径。
下面以类的形式编写爬虫程序,并在类下编写不同的功能函数,代码如下所示:
from urllib import request
from urllib import parse
from fake_useragent import UserAgent
import time
import random
# 定义爬虫类
class TiebaSpider(object):
# 初始化url实例属性
def __init__(self):
self.url = "https://tieba.baidu.com/f?kw={}&pn={}"
# 请求函数,得到页面
def get_html(self, url):
# 使用第三方库设置UA
headers = {'User-Agent': UserAgent().firefox}
# 重构请求对象
req = request.Request(url=url, headers=headers)
response = request.urlopen(req)
# 返回整个页面
return response.read().decode('utf-8')
# 解析函数,此处代码暂时省略
def parse_html(self, html):
pass
# 该函数负责将抓取下来的数据保至数据库中,比如 MySQL、MongoDB 等,或者将其保存为文件格式,比如 csv、txt、excel 等
def save_html(self, filename, html):
with open(filename, 'w', encoding='utf-8') as f:
f.write(html)
# 入口函数
def run(self):
kw = input("请输入要爬取的关键字")
parse_kw = parse.quote(kw)
begin = int(input("请输入开始页"))
end = int(input("请输终止始页"))
pn = (begin - 1) * 50
for i in range(begin, end + 1):
# 重构文件名称
filename = f'{kw}_{i}.html'
# 拼接url
url = self.url.format(parse_kw, pn)
# 调用保存方法
self.save_html(filename, self.get_html(url))
print(f"第{i}页抓取成功")
# 每爬取一个页面随机休眠2-3秒钟的时间
time.sleep(random.randint(2, 3))
#以脚本的形式启动爬虫
if __name__ == '__main__':
start = time.time()
spider = TiebaSpider()
spider.run()
stop = time.time()
print('爬取完成,共耗%.2f时间' % (stop - start))
程序执行后,爬取的文件将会保存至 Pycharm 当前工作目录,输出结果:
请输入要爬取的关键字python
请输入开始页1
请输终止始页5
第1页抓取成功
第2页抓取成功
第3页抓取成功
第4页抓取成功
第5页抓取成功
爬取完成,共耗23.88时间
用面向对象的方法编写爬虫程序时,逻辑结构较为固定,总结如下:
# 程序结构
class xxxSpider(object):
def __init__(self):
# 定义常用变量,比如url或计数变量等
def get_html(self):
# 获取响应内容函数,使用随机User-Agent
def parse_html(self):
# 使用正则表达式来解析页面,提取数据
def write_html(self):
# 将提取的数据按要求保存,csv、MySQL数据库等
def run(self):
# 主函数,用来控制整体逻辑
if __name__ == '__main__':
# 程序开始运行时间
spider = xxxSpider()
spider.run()
注意:掌握以上编程逻辑有助于您后续的学习。