python爬虫实战二之爬取百度贴吧帖子

目标:

1.对百度贴吧的任意帖子进行抓取

2.指定是否只抓取楼主发帖内容

3.将抓取到的内容分析并保存到文件

1.URL格式的确定

首先,我们先观察一下百度贴吧的任意一个帖子。比如:http://tieba.baidu.com/p/3138733512?see_lz=1&pn=1,分析一下地址

http://表示资源传输使用http协议

tieba.baidu.com 是百度的二级域名,指向百度贴吧的服务器。

/p/3138733512是服务器的某个资源,即这个帖子的地址定位符

see_lz和pn是该url的两个参数,分别代表了只看楼主和帖子页码,等于1表示该条件为真

所以我们可以讲url分为两部分,一部分为基础部分,一部分为参数部分。

例如上面的url我们划分基础部分是 http://tieba.baidu.com/p/3138733512,参数部分是?see_lz=1&pn=1

2.页面的抓取

熟悉了URL的格式,那就让我们用urllib2库来试着抓取页面内容吧。上一篇糗事百科我们最后改成了面向对象的编码方式,这次我们直接尝试一下,定义一个类名叫BDTB(百度贴吧),一个初始化方法,一个获取页面的方法。

其中,有些帖子我们想指定给程序是否要只看楼主,所以我们把只看楼主的参数初始化放在类的初始化上,即init方法。另外,获取页面的方法我们需要知道一个参数就是帖子页码,所以这个参数的指定我们放在该方法中。

综上,我们初步构建出基础代码如下:

import urllib.request
from urllib.request import urlopen
import urllib.error
import re
#百度贴吧爬虫类
class BDTB:
#初始化,传入基地址,是否只看楼主的参数
    def __init__(self,baseurl,seeLZ):
        self.baseURL=baseurl
        self.seeLZ='?see_lz='+str(seeLZ)
    #传入页码,获取该页帖子的代码
    def getPage(self,pageNum):
        try:
            url=self.baseURL+self.seeLZ+'&pn'+str(pageNum)
            request=urllib.request.Request(url)
            response=urllib.request.urlopen(request)
            print(response.read().decode('utf-8'))
            return response
        except urllib.error.URLError as e:
            if hasattr(e,'reason'):
                print(u'连接百度贴吧失败,错误原因',e.reason)
                return None
baseURL='http://tieba.baidu.com/p/3138733512'
bdtb=BDTB(baseURL,1)
bdtb.getPage(1)
部分运行结果:(可以看到屏幕上打印出了这个帖子第一页楼主发言的所有内容,形式为HTML代码)

  <a data-field='{&quot;un&quot;:&quot;\u660e\u4e4b\u7ffc&quot;}'alog-group="p_author" class="p_author_name j_user_card" href="/home/main?un=%E6%98%8E%E4%B9%8B%E7%BF%BC&ie=utf-8&fr=pb" target="_blank">明之翼</a>
                    
                </li>
                
                <li class="l_badge" style="display:block;">
                    <div class="p_badge">
                        <a href="/f/like/level?kw=nba&ie=utf-8&lv_t=lv_nav_intro" target="_blank" class="user_badge d_badge_bright d_badge_icon3_1" title="本吧头衔12级,经验值6206,点击进入等级头衔说明页"><div class="d_badge_title ">MVP</div><div class="d_badge_lv">12</div></a>
                    </div>

3.提取相关信息

1)提取帖子标题

关于标题的源代码:

<h3 class="core_title_txt pull-left text-overflow" title="纯原创我心中的NBA2014-2015赛季现役50大" style="width: 396px">纯原创我心中的NBA2014-2015赛季现役50大</h3>

所以我们想提取<h3>标签中的内容,同时还要指定这个class唯一,因为h3标签实在太多,正则表达式如下

<h3 class="core_title_txt .*?>(.*?)</h3>

所以我们增加一个获取标题的方法

def getTitle(self):
    page=self.getPage(1)
    pattern=re.compile('<h3 class="core_title_txt .*?>(.*?)</h3>',re.S)
    result=re.search(pattern,page)
    if result:
        #print result.group(1)#测试输出
        return result.group(1).strip()
    else:
        return None

2)提取帖子页数

同样的 帖子总页数我们也可以通过分析页面中的?页来获取,所以我们的获取总页数的方法如下

#获取帖子一共有多少页
def getPageNum(self,page):
    pattern=re.compile('<li class="l_reply_num" .*?</span>.*?<span.*?>(.*?)</span>',re.S)
    result=re.search(pattern,page)
    if result:
        #print result.group(1)测试输出
        return result.group(1).strip()
    else:
        return None

3)提取正文内容

def getContent(self,page):
    pattern=re.compile('<div id="post_content_.*?>(.*?)</div>',re.S)
    items=re.findall(pattern,page)
    for item in items:
        print(item)
运行部分结果:

很多媒体都在每赛季之前给球员排个名,我也有这个癖好…………,我会尽量理性的分析球队地位,个人能力等因素,评出我心目中的下赛季50大现役球员,这个50大是指预估他本赛季在篮球场上对球队的影响力……不是过去的荣誉什么的,所以难免有一定的主观性……如果把你喜欢的球星排低了,欢迎理性讨论!<img class="BDE_Image" src="https://imgsa.baidu.com/forum/w%3D580/sign=557ae4d4fadcd100cd9cf829428947be/a9d6277f9e2f0708468564d9eb24b899a801f263.jpg" pic_ext="jpeg"  pic_type="0" width="339" height="510"><br><br><br><br>状元维金斯镇楼<br>P.S 1 我每天都至少更新一个,不TJ。<br>      2 今年的新秀我就不考虑了,没上赛季参照
            <img class="BDE_Image" src="https://imgsa.baidu.com/forum/w%3D580/sign=cb6ab1f8708b4710ce2ffdc4f3ccc3b2/06381f30e924b899d8ca30e16c061d950b7bf671.jpg" pic_ext="jpeg"  pic_type="0" width="339" height="510"><br><br><br><br>50 惊喜新人王 <a href="http://jump2.bdimg.com/safecheck/index?url=x+Z5mMbGPAsY/M/Q/im9DR3tEqEFWbC4Yzg89xsWivS12AkS11WcjnMQsTddE2yXZInIi4k8KEu5449mWp1SxBADVCHPuUFSTGH+WZuV+ecUBG6CY6mAz/Zq1mzxbFxzAG+4Cm4FSU0="  class="ps_cb" target="_blank" οnclick="$

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值