写在前面的话 :上一篇文章我们初步学习了python中re模块的基本使用,所以下面我们就结合urllib和re来爬取百度贴吧吧
温馨提示 :博主使用的操作系统为win10,使用的python版本为3.6.5,使用的网页分析工具为Chrome浏览器自带的开发者工具
一、网页分析
首先我们需要使用浏览器对目标网站进行分析,用Chrome浏览器打开百度贴吧,在输入栏中输入关键字进行搜索,这里示例为“计算机吧”
接下来我们就需要分析网页了,观察URL发现,它的URL十分有规律,这里我们只关注两个比较重要的参数,一个是搜索的关键字,另一个是当前页面的页码,其URL规律可以书写如下:http://tieba.baidu.com/f?kw={keyword}&ie=utf-8&pn={page},但是值得注意的是这里的page是以50为步幅的,也就是说第一页的URL是http://tieba.baidu.com/f?kw={keyword}&ie=utf-8&pn=0,而第二页的URL是http://tieba.baidu.com/f?kw={keyword}&ie=utf-8&pn=50,以此类推,所以我们可以通过构造URL来获取每一页的内容
接下来我们直接使用快捷键 Ctrl+U
打开网页的源代码分析每一页的内容,我们需要抓取的数据有:每一个帖子的主题名称、主题作者、链接地址、回复数和创建日期,我们通过第一个帖子的主题名称——“【计算机吧】吧规”来定位到我们需要的位置,发现每一个主题帖子的信息包含在一个li标签中,然后我们通过正则表达式匹配每一个帖子的每一项信息
- 主题名称:
r'href="/p/\d+" title="(.+?)"'
- 主题作者:
r'title="主题作者: (.+?)"'
- 链接地址:
r'href="/p/(\d+)"'
- 回复数:
r'title="回复">(\d+)<'
- 创建日期:
r'title="创建时间">(.+?)<'
二、编码实现
#-*-coding:utf-8-*-
import urllib.request
import urllib.parse
import re
import time
import random
class TiebaSpider():
#初始化
def init(self):
#用户输入的搜索关键字,即主题贴吧名称
self.keyword = input('请输入主题贴吧名字:')
#网页的初始化链接地址,用urllib.parse.quote()函数可以对中文进行转码
self.base_url = 'http://tieba.baidu.com/f?kw=' + urllib.parse.quote(self.keyword) + '&ie=utf-8&pn={page}'
#获得网页源代码
def get_page(self,page):
#请求信息:Request URL
url = self.base_url.format(page=page)
#请求信息:Request Headers
headers = {
'USER-AGENT':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36'
}
#构造请求对象
req = urllib.request.Request(url=url,headers=headers,method='GET')
#发送请求,得到响应
response = urllib.request.urlopen(req)
#获得网页源代码
html = response.read().decode('utf-8')
#返回网页源代码
return html
#解析网页源代码,提取数据
def parse_page(self,html):
#帖子的主题名称
titles = re.findall(r'href="/p/\d+" title="(.+?)"',html)
#帖子的主题作者
authods = re.findall(r'title="主题作者: (.+?)"',html)
#帖子的链接地址
nums = re.findall(r'href="/p/(\d+)"',html)
links = []
for item in nums:
links.append('http://tieba.baidu.com/p/' + item)
#帖子的回复数量
focus = re.findall(r'title="回复">(\d+)',html)
#帖子的创建时间
ctimes = re.findall(r'title="创建时间">(.+?)<',html)
#将所有的信息储存在列表中,列表的每一项为一个字典,对应一个主题帖子的信息
result = []
for i in range(len(titles)):
item = {}
item['title'] = titles[i]
item['authod'] = authods[i]
item['link'] = links[i]
item['focus'] = focus[i]
item['ctime'] = ctimes[i]
result.append(item)
#返回列表
return result
def start_spider(self):
#初始化
self.init()
#获取总共的帖子数量,便于构造URL
html = self.get_page(0)
total_page = re.findall(r'共有主题数<span class="red_text">(\d+)</span>个',html)
total_page = int(total_page[0])
#构造URL获取每一页的帖子信息
page = 0
count = 0
f = open(spider.keyword+'.txt','w',encoding='utf-8')
print('Processing...')
while page <= total_page :
html = self.get_page(page)
result = self.parse_page(html)
for i in range(len(result)):
count += 1
f.write('--------------------'+str(count)+'--------------------\n')
f.write(result[i]['title'])
f.write('\n')
f.write(result[i]['authod'])
f.write('\n')
f.write(result[i]['link'])
f.write('\n')
f.write(result[i]['focus'])
f.write('\n')
f.write(result[i]['ctime'])
f.write('\n')
print(count)
page += 50
time.sleep(random.random())
f.close()
print('Finished')
if __name__ == '__main__':
spider = TiebaSpider()
spider.start_spider()
写在后面的话 :通过前面的学习,我们已经掌握了urllib的基本使用方法了,但是urllib的使用虽然是基础的,但却有些许麻烦,所以下一篇文章我们将学习更加强大更加便捷的HTTP请求库,谢谢大家