用urllib和re爬取百度贴吧

写在前面的话上一篇文章我们初步学习了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请求库,谢谢大家

猜你喜欢

转载自blog.csdn.net/wsmrzx/article/details/81780241