Python爬虫案例2:百度贴吧内容爬取
作者:Barranzi_
个人github主页:[github](https://github.com/La0bALanG)
个人邮箱:awc19930818@outlook.com
新时代的铁饭碗:一辈子不管走到哪里都有饭吃(还能吃上热乎的)。——佚名
免责声明:
本系列笔记撰写初衷就是为了分享个人知识以及个人学习历程中的感悟及思考,所涉及到的内容`仅供学习与交流`,请勿用作`非法或商业用途`!由此引发的任何法律纠纷`后果自负`,与作者本人无关!
版权声明:
未经作者本人授权,禁止转载!请尊重原创!

注:本文所有代码、案例测试环境:1.Linux -- 系统版本:Ubuntu20.04 LTS 2.windows -- 系统版本:WIN10 64位家庭版
请求URL及页面数据分析
-
目标URL
百度贴吧首页:https://tieba.baidu.com/index.html
-
目标数据
随意搜索贴吧名称,进入该吧主页,获取其页面数据
-
URL分析
根据随意搜索的多个吧名,抓取其URL:
https://tieba.baidu.com/f?kw=%E9%95%BF%E6%B2%99&ie=utf-8&pn=0 https://tieba.baidu.com/f?kw=%E6%9D%8E%E6%AF%85&ie=utf-8&pn=0 ...分析该URL,获得其规律如下:
- kw查询关键字,需要实时传参;
- pn页码参数,单位50,代表当前第几页;
- 查询参数因为是汉字,传入时需要先转成urlencode编码
总结其URL基本格式如下:
https://tieba.baidu.com/f?kw={}&ie=utf-8&pn={} -
页面及所需数据分析
无所需解析数据,请求到页面后直接写入其response内容即可。
编码分析
-
第一步:构造URL基本格式,伪造headers
headers = { 'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.83 Safari/537.36' } url = 'https://tieba.baidu.com/f?kw={}&ie=utf-8&pn={}' #构造起始页及终止页 begin = int(input('请输入起始页:')) end = int(input('请输入终止页:')) #查询页码数量:end - begin # page = end - begin #构造查询参数并转urlencode编码 kw = input('请输入您想搜索的贴吧名称>>>:') parmas = parse.quote(kw) #依据页码构造最终n个URL for page in range(begin,end + 1): pn = (page - 1) * 50 # print(pn) finall_url = url.format(parmas,pn) -
第二步:发请求,获得响应,内容转为二进制,等待文件写入
reqs = request.Request(url=finall_url,headers = headers) #2.发起正式请求并解码请求内容 resp = request.urlopen(reqs).read() -
第三步:写入文件
filename = kw + '吧' + '_第%d页.html'%page with open(filename,'wb') as f: f.write(resp) f.close()
编码实现
-
基础编码
# -*- coding:utf-8 _*- """ @version: author:安伟超 @time: 2020/09/07 @file: demo01_baidutieba_simple.py @environment:virtualenv @email:awc19930818@outlook.com @github:https://github.com/La0bALanG @requirement:1.输入贴吧名称 2.输入起始页 3.输入终止页 4.保存响应的页面内容至txt文档 """ from urllib import request,parse """ 思路: 1.分析页面URL规律 2.构造查询参数 3.发起请求获得响应 4.写入文件 """ """ 1.分析页面URL规律 打开百度贴吧,随便搜索一个吧,进入,提取出URL: https://tieba.baidu.com/f?kw=%E9%95%BF%E6%B2%99&ie=utf-8&pn=0 https://tieba.baidu.com/f?kw=%E6%9D%8E%E6%AF%85&ie=utf-8&pn=0 ... 查找规律: 1.kw查询关键字,需要实时传参; 2.pn页码参数,单位50,代表当前第几页 3.查询参数因为是汉字,传入时需要先转成urlencode编码 总结URL基本格式: https://tieba.baidu.com/f?kw={}&ie=utf-8&pn={} 所以,总结思路如下: 1.构造基本URL格式 2.构造查询起始页及终止页页码数 3.构造查询参数及页码参数 4.字符串拼接,完成最终URL确定格式 """ """ 确定URL后: 1.伪造headers 2.发起正式请求 """ """ 获得具体响应内容后: 写入文件 """ #伪造headers headers = { 'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.83 Safari/537.36' } #构造基本URL格式 url = 'https://tieba.baidu.com/f?kw={}&ie=utf-8&pn={}' #构造起始页及终止页 begin = int(input('请输入起始页:')) end = int(input('请输入终止页:')) #查询页码数量:end - begin # page = end - begin #构造查询参数并转urlencode编码 kw = input('请输入您想搜索的贴吧名称>>>:') parmas = parse.quote(kw) #依据页码构造最终n个URL for page in range(begin,end + 1): pn = (page - 1) * 50 # print(pn) finall_url = url.format(parmas,pn) #测试URL格式 # print(finall_url) #发请求 #1.创建请求对象 print('开始爬取第%d页...'%page) reqs = request.Request(url=finall_url,headers = headers) #2.发起正式请求并解码请求内容 resp = request.urlopen(reqs).read() # print(resp) print('第%d页爬取完成,稍等,马上开始写入文件内容...'%page) # 写入文件: filename = kw + '吧' + '_第%d页.html'%page with open(filename,'wb') as f: f.write(resp) f.close() print('文件写入完毕,开始下一页爬取...') print('程序结束。') -
面向对象编程
# -*- coding:utf-8 _*- """ @version: author:安伟超 @time: 2020/09/07 @file: demo01_baidutieba_simple.py @environment:virtualenv @email:awc19930818@outlook.com @github:https://github.com/La0bALanG @requirement:1.输入贴吧名称 2.输入起始页 3.输入终止页 4.保存响应的页面内容至txt文档 """ import threading from urllib import request, parse """ 思路: 1.分析页面URL规律 2.构造查询参数 3.发起请求获得响应 4.写入文件 """ """ 1.分析页面URL规律 打开百度贴吧,随便搜索一个吧,进入,提取出URL: https://tieba.baidu.com/f?kw=%E9%95%BF%E6%B2%99&ie=utf-8&pn=0 https://tieba.baidu.com/f?kw=%E6%9D%8E%E6%AF%85&ie=utf-8&pn=0 ... 查找规律: 1.kw查询关键字,需要实时传参; 2.pn页码参数,单位50,代表当前第几页 3.查询参数因为是汉字,传入时需要先转成urlencode编码 总结URL基本格式: https://tieba.baidu.com/f?kw={}&ie=utf-8&pn={} 所以,总结思路如下: 1.构造基本URL格式 2.构造查询起始页及终止页页码数 3.构造查询参数及页码参数 4.字符串拼接,完成最终URL确定格式 """ """ 确定URL后: 1.伪造headers 2.发起正式请求 """ """ 获得具体响应内容后: 写入文件 """ class BaiduTiebaSpider(object): """ 面向对象思路: 1.拆分功能细节。整体程序可拆分为: 1.发请求获得页面 2.解析页面 3.持久化存储(写入文件保存) 2.结合开闭原则,封装功能方法为私有方法,对外提供统一公共接口 3.采用单例模式:假设本爬虫程序在多个时间、不同情况下多次使用,单例模式实现只创建一个对象,提升性能避免内存占用过高。 """ #添加线程锁,避免实际运行过程中受多线程影响 _instance_lock = threading.Lock() def __init__(self): self.__url = 'https://tieba.baidu.com/f?kw={}&ie=utf-8&pn={}' #单例模式实现:__new__方法 def __new__(cls, *args, **kwargs): if not hasattr(BaiduTiebaSpider, '_instance'): with BaiduTiebaSpider._instance_lock: if not hasattr(BaiduTiebaSpider, '_instance'): BaiduTiebaSpider._instance = object.__new__(cls) return BaiduTiebaSpider._instance #设置只读属性,体现封装思想 @property def url(self): return self.__url def __get_html(self,url): # 伪造headers headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.83 Safari/537.36' } # 发请求 # 1.创建请求对象 reqs = request.Request(url=url, headers=headers) # 2.发起正式请求,获得页面响应数据 return request.urlopen(reqs).read() def __parse_html(self): pass def __save_html(self,filename,html): with open(filename,'wb') as f: f.write(html) def display(self): # 构造起始页及终止页 begin = int(input('请输入起始页:')) end = int(input('请输入终止页:')) # 查询页码数量:end - begin # page = end - begin # 构造查询参数并转urlencode编码 kw = input('请输入您想搜索的贴吧名称>>>:') parmas = parse.quote(kw) # 依据页码构造最终n个URL for page in range(begin, end + 1): pn = (page - 1) * 50 # print(pn) finall_url = self.__url.format(parmas, pn) html = self.__get_html(finall_url) filename = kw + '吧' + '_第%d页.html'%page self.__save_html(filename,html) def test(): BaiduTiebaSpider().display() if __name__ == '__main__': test()


