目录
需求分析
本篇介绍的小程序可以用于爬取百度贴吧的数据,要求输入贴吧名称,输入起始页和终止页,然后将网页下载下来保存到本地。
程序执行步骤分析
1.输入贴吧名称
2.输入起始页
3.输入终止页
网页URL分析
尝试在百度贴吧搜索李毅,得出来的结果如下图:
去除一些不必要参数后,可以得到:
那么最终的结果为https://tieba.baidu.com/f?kw=李毅。
进一步分析后,可以发现‘https://tieba.baidu.com/f?kw=’为固定的一段,‘李毅’这个参数名是动态的,取决于你输入的搜索值是什么。
分析完搜索参数后再来看页码,经过我们的分析后,得出第一页的URL为:
第二页的URL为:
依次推列,得到页码的规律,page=(n-1)*50 (n>=1) 。
经过参数和页码分析后,得出的分析结果如下:
URL分析结果:https://tieba.baidu.com/f?kw={value}&pn=(n-1)*50
程序框架设计
1.生成一个类,封装方法
2.方法1,用于获取html页面:get_html()
3.方法2,用于将获取的页码存盘:save_local()
4.方法3,程序入口,用于获取参数和调用方法1,2
程序代码
本程序需要注意的有以下:
1.注意decode,response.read()获取到的是二进制文本,需要decode转换为string
2.注意存盘时的encoding,由于上面进行了decode,这里要对应
3.注意转码,parse.quote方法可以将中文字符串转换为可执行编码,url请求不接受中文参数
4.注意控制爬取速度,如果爬取速度过快会触发百度的安全机制。需要使用sleep方法休眠
5.如果在执行过程中遇到utf-8 cannot decode问题。可以将html=rep.read().decode('utf-8')这一句改为 html=rep.read().decode('utf-8','ignore'),忽略掉。
请看一下代码:
from urllib import request,parse
import time
import random
class baiduCrawl(object):
#初始化url,headers
def __init__(self):
self.url="http://tieba.baidu.com/f?kw={}&pn={}"
self.headers={"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36"}
self.dir="C:\\Users\\Administrator\\Desktop\\新建文件夹\\"
# 获取页面
def get_html(self,url):
req=request.Request(url=url,headers=self.headers)
rep=request.urlopen(req)
html=rep.read().decode('utf-8')
return html
# 存盘
def save_local(self,filename,html):
with open(filename,'w',encoding='utf-8') as f:
f.write(html)
# 程序入口函数
def run(self):
# 获取基本信息
name=input("请输入贴吧名:")
# 注意这里输入的页码数必须大于等于1
page_start=int(input("请输入起始页:"))
page_end=int(input("请输入终止页:"))
params=parse.quote(name)
for page in range(page_start,page_end+1):
pn=(page-1)*50
url=self.url.format(params,pn)
# 获取页面
html=self.get_html(url)
# 保存到本地
filename=self.dir+"{}_第{}页.html".format(name,page)
self.save_local(filename,html)
# 控制爬取速度
time.sleep(random.randint(1,2))
# uniform为浮点型,执行速度比整形快
# time.sleep(random.uniform(1,2))
print("第%d页抓取完成"%page)
if __name__=="__main__":
spider=baiduCrawl()
spider.run()