找回密码
 立即注册

扫一扫,访问微社区

QQ登录

只需一步,快速开始

查看: 5756|回复: 1

[代码与实例] python爬取百度贴吧帖子,并写入txt文档

0

主题

0

帖子

0

积分

贫民

积分
0
拧发条鸟 发表于 2016-10-21 22:21:01 | 显示全部楼层 |阅读模式
本帖最后由 拧发条鸟 于 2016-10-21 22:25 编辑

最近笔者在学习python,以python爬虫作为项目进行实践.
本篇主要学习于Python爬虫实战二之爬取百度贴吧帖子 | 静觅,主体思路大体相同.
爬取代码->正则提取关键信息->写入文件,三大步骤
但是笔者针对程序的的运行效率,编码处理,输入检验,做了适当更改,使得更好的面向客户.
欢迎各位读者大人提出意见和建议.
  1. #encoding:utf-8
  2. #v4版本较于v3需要进行数据检测
  3. #是否是百度网页,是否输入1/0
  4. import urllib2
  5. import urllib
  6. import sys
  7. import re
  8. #内容修正包,及url修正包
  9. class Tool:
  10.     #去除img标签,7位长空格
  11.     removeImg=re.compile(r'<img.*?>| {7}')
  12.     #去除超链接
  13.     removehref=re.compile(r"<a href=.*?>|</a>")
  14.     #换掉换行符\n
  15.     replaceline=re.compile(r"<st>|<div>|</div>|</p>")
  16.     #段落开头换回\n加空两个
  17.     replacePara=re.compile(r"<p.*?>")
  18.     #制表符<td>替换为\t
  19.     replaceTD=re.compile(r"<td>")
  20.     #换行符或双换行符替换为\n
  21.     replaceBR=re.compile(r'<br><br>|<br>')
  22.     #去其他标签
  23.     removeExtraTag=re.compile('<.*?>')
  24.     #去除URL中冗余信息
  25.     removeURL=re.compile('\?.*')
  26.     def replace(self,x):
  27.         x=re.sub(self.removeImg,"",x)
  28.         x=re.sub(self.removehref,"",x)
  29.         x=re.sub(self.replaceline,"\n",x)
  30.         x=re.sub(self.replaceBR,"\n    ",x)
  31.         x=re.sub(self.replacePara,"\n    ",x)
  32.         x=re.sub(self.replaceTD,"\t",x)
  33.         x=re.sub(self.removeExtraTag,"",x)
  34.         #strip()将前后多余内容删除
  35.         return x.strip()

  36.     def cheakURL(self,x):
  37.         x=re.sub(self.removeURL,'',x)
  38.         return x.strip()

  39. #百度爬虫类
  40. class Spider_Baidu:
  41.     #初始参数
  42.     def __init__(self,baseurl,see_lz=1,tag=1):
  43.         self.tag=tag#是否要楼
  44.         self.defualtname="百度贴子"#默认名称
  45.         self.file=None#文件
  46.         self.see_lz=see_lz#是否看楼主
  47.         self.baseURL=baseurl
  48.         self.tool=Tool()
  49.         self.floor=1
  50.     #获取源代码,返回源代码
  51.     def getPage(self,index):
  52.         url = self.tool.cheakURL(self.baseURL)+ "?see_lz=" + str(self.see_lz) + "&pn=" + str(index)
  53.         request = urllib2.Request(url)
  54.         try:
  55.             response = urllib2.urlopen(request)
  56.             pagecode = response.read().decode("utf-8")
  57.             return pagecode
  58.         except urllib2.URLError,e:
  59.             print u"连接失败,失败原因为",e.reason
  60.             return None
  61.     #获取总页数,
  62.     def getPageNum(self,pagecode=None):
  63.         if not pagecode:pagecode=self.getPage(1)
  64.         if not pagecode:return None#如果读取失败返回None
  65.         pattern=re.compile(r'''<span class="red">(.*?)<''',re.S)
  66.         pagenum=re.findall(pattern,pagecode)
  67.         if pagenum:return pagenum[0]
  68.         else:return None

  69.     #获取帖子标题
  70.     def getTitle(self,pagecode=None):
  71.         if not pagecode:pagecode=self.getPage(1)
  72.         if not pagecode:return None
  73.         pattern = re.compile(r'''<h3 class="core_title_txt.*?>(.*?)</h3>''', re.S)
  74.         headline = re.findall(pattern, pagecode)
  75.         if headline:
  76.             return headline[0]
  77.         else:
  78.             return None

  79.     #获取正文内容
  80.     def getContent(self,pagecode):
  81.         pattern = re.compile(r'''<div id="post_content_.*?>(.*?)</div>''', re.S)
  82.         items = re.findall(pattern, pagecode)
  83.         content=[]
  84.         for item in items:
  85.             content.append("\n"+self.tool.replace(item)+"\n")
  86.         if content:return content
  87.         else:return None

  88.     #打开文件
  89.     def opentxt(self,title=None):
  90.         if not title: title = self.getTitle()
  91.         if title:self.file=open(title+".txt",'w+')
  92.         else:self.file=open(self.defualtname+".txt",'w+')

  93.     #写入文件,如果要设计写入是一个单纯的函数,那么应该将floor定义在函数之外
  94.     def txtwrite(self,contends):
  95.         # floor=1
  96.         if self.tag:
  97.             floorlLine = '\n' + str(self.floor)+'楼' + \
  98.                          u"---------------" \
  99.                          u"----------------" \
  100.                          u"-----------------" \
  101.                          u"--------------------" \
  102.                          u"---------------------\n"
  103.             self.floor+=1
  104.             self.file.write(floorlLine)
  105.         self.file.write(contends)
  106.         return True

  107.     #开始函数
  108.     def start(self):
  109.         indexpage=self.getPage(1)
  110.         pageNum=self.getPageNum(indexpage)
  111.         title=self.getTitle(indexpage)
  112.         if pageNum == None:
  113.             print "URL已失效,请重试"
  114.             return None
  115.         self.opentxt(title)
  116.         try:
  117.             print u"该帖子共" + pageNum + u"页"
  118.             for i in range(1,int(pageNum)+1):
  119.                 print u"正在写入第" + str(i) + u"页数据"
  120.                 code=self.getPage(i)
  121.                 content=self.getContent(code)
  122.                 for item in content:
  123.                     self.txtwrite(item)
  124.             #出现写入异常
  125.         except IOError,e:
  126.             print u"写入异常"+e.message
  127.         finally:
  128.             print u"写入完成"

  129. #输入数据类
  130. class Inputdata:
  131.     baseurl=None
  132.     seezl=None
  133.     floorTag=None
  134.     baidu=re.compile(r"tieba.baidu.com/p")
  135.     def datainput(self):
  136.         print u"请输入帖子网址"
  137.         self.baseurl =raw_input()
  138.         while not re.search(self.baidu,self.baseurl):
  139.             print u"非百度贴吧,请再次输入"
  140.             self.baseurl = raw_input()
  141.         self.seelz = raw_input(u"是否只获取楼主发言,是输入1,不是输入0\n")
  142.         while self.seelz!="1" and self.seelz!="0":self.seelz = raw_input(u"请输入0或1\n")

  143.         self.floorTag = raw_input(u"是否写入楼层信息,是输入1,否输入0\n")
  144.         while self.floorTag!="1" and self.floorTag!="0":self.floorTag = raw_input(u"请输入0或1\n")



  145. import sys
  146. import time
  147. reload(sys)
  148. sys.setdefaultencoding('utf-8')#处理转码问题
  149. data=Inputdata()
  150. data.datainput()
  151. print data.baseurl,data.seelz,data.floorTag
  152. spider=Spider_Baidu(data.baseurl,data.seelz,data.floorTag)
  153. start=time.clock()#计算爬取所用时间
  154. spider.start()
  155. end=time.clock()
  156. print u"用时:%f s"%(end-start)
  157. raw_input(u"按任意键退出")
  158. exit(0)
复制代码

回复

使用道具 举报

0

主题

18

帖子

18

积分

贫民

积分
18
kushao1267 发表于 2016-10-25 18:10:20 | 显示全部楼层
urllib2版本也太老了,建议用requests试试。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表