Python学习-百度贴吧爬虫练习(Python自带爬虫模块)

  • 要求
    1、输入要爬取的贴吧的主题;2、输入要爬取的起始页和终止页;3、把每一页的网页源码保存到本地的html文件中。

  • 分析
    1、贴吧的主题直接用 input()方法就可以从用户那里获取到。
    2、起始页和终止页,观察:
    第一页 https://tieba.baidu.com/f?kw=%E6%B5%B7%E8%B4%BC%E7%8E%8B&ie=utf-8&pn=0
    第二页 https://tieba.baidu.com/f?kw=%E6%B5%B7%E8%B4%BC%E7%8E%8B&ie=utf-8&pn=50
    第三页 https://tieba.baidu.com/f?kw=%E6%B5%B7%E8%B4%BC%E7%8E%8B&ie=utf-8&pn=100
    ……
    可以发现pn值在变化,相邻的一页相差50,第一页为0,第二页为50,以此类推,所以页数 pn=(当前页数-1)*50,另外kw值为贴吧的主题。

  • 方式一:

import urllib.request
import urllib.parse
import random
# 首先随机获取一个 User-Agent,可以先从网上查找一些 User-Agent,然后存放在列表里
headers_list = [{'User-Agent-1':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.835.163 Safari/535.1'},{'User-Agent-2':'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:6.0) Gecko/20100101 Firefox/6.0'},{'User-Agent-3':'Opera/9.80 (Windows NT 6.1; U; zh-cn) Presto/2.9.168 Version/11.50'}]
headers = random.choice(headers_list)
name = input('请输入要搜索的贴吧主题:')
start_page = int(input('请输入起始页:'))
end_page = int(input('请输入终止页:'))
# 对贴吧主题name进行编码
kw = urllib.parse.quote(name)
baseurl = 'https://tieba.baidu.com/f?kw='
# 开始拼接url、发起请求、获取响应
for i in range(start_page,end_page+1):
	pn = (i-1)*50
	# 拼接url
	url = baseurl + kw + '&ie=utf-8&pn=' + str(pn)
	# 发起请求
	req = urllib.request.Request(url,headers=headers)
	# 获取响应
	ob = urllib.request.urlopen(req)
	# 读取响应内容
	html = ob.read().decode('utf-8')
	# 构造文件名,并将网页源码写入文件中
	html_name = '第'+str(i)+'页.html'
	with open(html_name,'w',encoding='utf-8') as file:
		print('正在爬取第{}页。'.format(i))
		file.write(html)

print('爬取完毕。')
	
  • 方式二
    用函数的方式来实现,优化方式一。
import urllib.request
import urllib.parse
import random

# 读取页面
def readpage(url):
	# 获取随机请求头
	headers_list = [{'User-Agent-1':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.835.163 Safari/535.1'},{'User-Agent-2':'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:6.0) Gecko/20100101 Firefox/6.0'},{'User-Agent-3':'Opera/9.80 (Windows NT 6.1; U; zh-cn) Presto/2.9.168 Version/11.50'}]
	headers = random.choice(headers_list)
	# 发起请求
	response = urllib.request.Request(url,headers=headers)
	# 获取相应内容
	object = urllib.request.urlopen(response)
	# 读取响应对象的内容
	html = object.read().decode('utf-8')
	# 返回读取到的内容
	return html

# 写入文件
def writepage(filename,html):
	with open(filename,'w',encoding='utf-8') as file:
		file.write(html)

# 主函数
def main():
	name = input('请输入要搜索的贴吧主题:')
	start_page = int(input('请输入起始页:'))
	end_page = int(input('请输入终止页:'))
	# 对贴吧主题name进行编码
	kw = urllib.parse.quote(name)
	baseurl = 'https://tieba.baidu.com/f?kw='
	for i in range(start_page,end_page+1):
		pn = (i-1)*50
		# 拼接url
		url = baseurl + kw + '&ie=utf-8&pn=' + str(pn)
		# 调用readpage()函数
        html = readpage(url)
        html_name = '第' + str(i) + '页.html'
        # 调用writepage()函数
        writepage(html_name,html)

# 用特殊方法__name__来调整程序的开始执行位置
if __name__ == '__main__':
	main()

这里需要补充一下:(这个知识点来自别的博客文章的整理)
(1)if __ name __ == '__ main __'的作用是:

  • 当.py文件被直接运行时,if __ name__ == '__ main__'之下的代码块将被运行;
  • 当.py文件以模块形式被导入时,if __ name__ == '__ main__'之下的代码块不被运行。

(2)if __ name__ == ‘__ main__’ 相当于Python模拟的程序入口,Python本身并没有这么规定,这只是一种编码习惯。由于模块之间相互引用,不同模块可能有这样的定义,而程序入口只有一个。到底哪个程序入口被选中,这取决于__name__的值。

  • 方式三
    用类的方式来实现,继续优化
import urllib.request
import urllib.parse

class TiebaSpider():
	# 初始化
	def __init__(self):
	# 把常用的不变的放到init方法里面,重复演示随机获取请求头了
	 	self.headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36'
        }
        self.baseurl = 'https://tieba.baidu.com/f?kw='
	
	# 读取页面
	def readpage(self,url):
		# 发起请求
		response = urllib.request.Request(url,headers=self.headers)
		# 获取响应内容
		object = urllib.request.urlopen(response)
		# 读取响应对象的内容
		html = object.read().decode('utf-8')
		# 返回读取到的内容
		return html
	
	# 写入文件
    def writepage(self,filename,html):
        with open(filename,'w', encoding='utf-8') as file:
            file.write(html

	def main(self):
		name = input('请输入要搜索的贴吧主题:')
        start_page = int(input('请输入起始页:'))
        end_page = int(input('请输入终止页:'))
        # 对贴吧主题name进行编码
        kw = urllib.parse.quote(name)
        for i in range(start_page, end_page + 1):
            pn = (i - 1) * 50
            # 拼接url
            url = self.baseurl + kw + '&ie=utf-8&pn=' + str(pn)
            html = self.readpage(url)
            html_name = '第' + str(i) + '页.html'
            self.writepage(html_name, html)
        # readpage()和writepage()前面的self指向的是类的实例,谁调用类就是谁
        print('爬取结束。')

if __name__ == '__main__':
	# 创建类的实例
	a = TiebaSpider()
	a.main()

你可能感兴趣的:(Python学习)