《python爬虫实战》:爬取贴吧上的帖子

来源:转载

《python爬虫实战》:爬取贴吧上的帖子

经过前面两篇例子的练习,自己也对爬虫有了一定的经验。
由于目前还没有利用BeautifulSoup库,因此关于爬虫的难点还是正则表达式的书写。

但是,当写几个正则表达式之后,发现还是有一定的规则可循的,只要我们的目的明确,想得到网页的什么,我们就直接在该网页上,找到我们想要的内容在html代码中出现的格式是怎么样的。

例如,我们想获取贴吧上帖子的标题。
解决方法为:在相应的网页的html代码中找到title出现的地方。然后提取正则表达式。

根据上面的截图:提取的正则表达式如下:

pattern=re.compile(r'<h3prettyprint">#得到帖子的标题 def getPageTitle(self,pageNum): content=self.getPageContent(pageNum)#得到网页的html代码 pattern=re.compile(r'<h3hljs-keyword">if title: #print title.group(1).strip() 测试输出 return title.group(1).strip() else: print None

同样的道理,我们可以得到获取帖子作者的代码如下:

#得到帖子的作者 def getPageAuthor(self,pageNum): content=self.getPageContent(pageNum) # <div author="懂球君"> pattern=re.compile(r'<div author="(.*?)">',re.S) author=re.search(pattern,content) if author: print author.group(1).strip()#测试输出 return author.group(1).strip() else : print None

同样的道理,可以得到任何我们想要的内容。比例:帖子的回复总数等。

下面是完整代码:

#encoding=utf-8#功能:抓取百度贴吧中帖子的内容import urllib2import urllibimport re#定义一个工具类来处理内容中的标签class Tool: #去除img标签,7位长空格 removeImg=re.compile('<img.*?>| {7}|') #去除超链接标签 removeAddr=re.compile('<a.*?>|</a>') #把换行的标签换为/n replaceLine=re.compile('<tr>|<div>|</div>|</p>') #将表格制表<td>替换为/t replaceTD=re.compile('<td>') #把段落开头换为/n加空两格 replacePara=re.compile('<p.*?>') #将换行符或双换行符替换为/n replaceBR=re.compile('<br><br>|<br>') #将其余标签删除 removeExtraTag=re.compile('<.*?>') def replace(self,x): x=re.sub(self.removeImg,"",x) x=re.sub(self.removeAddr,"",x) x=re.sub(self.replaceLine,"/n",x) x=re.sub(self.replaceTD,"/t",x) x=re.sub(self.replacePara,"/n ",x) x=re.sub(self.replaceBR,"/n",x) x=re.sub(self.removeExtraTag,"",x) return x.strip()#定义一个类class BaiduTieBa: #初始化,传入地址,以及是否只看楼主的参数,floorTag:为1就是往文件中写入楼层分隔符 def __init__(self,url,seeLZ,floorTag): self.url=url self.seeLZ="?see_lz="+str(seeLZ) self.tool=Tool() #全局的文件变量 self.file=None #默认标题,如果没有获取到网页上帖子的标题,此将作为文件的名字 self.defultTitle="百度贴吧" #是否往文件中写入楼与楼的分隔符 self.floorTag=floorTag #楼层序号 self.floor=1 #根据传入的页码来获取帖子的内容太 def getPageContent(self,pageNum): url=self.url+self.seeLZ+"&pn="+str(pageNum) user_agent="Mozilla/5.0 (Windows NT 6.1)" headers={"User-Agent":user_agent} try: request=urllib2.Request(url,headers=headers) response=urllib2.urlopen(request) content=response.read().decode("utf-8") #print content #测试输出 return content except urllib2.URLError,e: if hasattr(e,"reason"): print e.reason #得到帖子的标题 def getPageTitle(self,pageNum): content=self.getPageContent(pageNum) pattern=re.compile(r'<h3hljs-keyword">if title: print title.group(1).strip() return title.group(1).strip() else: print None #得到帖子的作者 def getPageAuthor(self,pageNum): content=self.getPageContent(pageNum) # <div author="懂球君"> pattern=re.compile(r'<div author="(.*?)">',re.S) author=re.search(pattern,content) if author: print author.group(1).strip()#测试输出 return author.group(1).strip() else : print None #得到帖子的总页数和总回复数 def getPageTotalPageNum(self,pageNum): content=self.getPageContent(pageNum) #<li ><span >1</span>回复贴,共<span>1</span>页</li> pattern=re.compile(r'<li.*? >(.*?)</span>.*?<span>(.*?)</span>',re.S) totalPageNum=re.search(pattern,content) if totalPageNum: print totalPageNum.group(1).strip(),totalPageNum.group(2).strip()#测试输出 #print totalPageNum[0],totalPageNum[1] return totalPageNum.group(1).strip(),totalPageNum.group(2).strip()#第一个返回值为回复个数,第二个返回值为帖子的页数 else: print "没找到" print None #提取帖子的内容 def getContent(self,pageNum): content=self.getPageContent(pageNum) #html代码中的格式如下: #<div id="post_content_80098618952"> #一个省女性几千万人 比刘亦菲漂亮的可以找出几个</div> #提取正则表达式如下: pattern=re.compile(r'<div id="post_content_.*?>(.*?)</div>',re.S) items=re.findall(pattern,content) floor=1 contents=[] for item in items: #将每个楼层的内容进行去除标签处理,同时在前后加上换行符 tempContent="/n"+self.tool.replace(item)+"/n" contents.append(tempContent.encode("utf-8")) #测试输出 #print floor,u"楼-------------------------------------------/n" #print self.tool.replace(item) #floor+=1 return contents #将内容写入文件中保存 def writedata2File(self,contents): for item in contents: if self.floorTag=="1": #楼与楼之间的分隔符 floorLine=u"/n"+str(self.floor)+u"-------------------/n" self.file.write(floorLine) print u"正在往文件中写入第"+str(self.floor)+u"楼的内容" self.file.write(item) self.floor+=1 #根据获取网页帖子的标题来在目录下建立一个同名的.txt文件 def newFileAccTitle(self,title): if title is not None: self.file=open(title+".txt","w+") else: self.file=open(defultTitle+".txt","w+") #写一个抓取贴吧的启动程序 def start(self,pageNum): #先获取html代码 content=self.getPageContent(pageNum) #第二步:开始解析,获取帖子的标题和作者 title=self.getPageTitle(pageNum) #根据title建立一个即将用于写入的文件 self.newFileAccTitle(title) author=self.getPageAuthor(pageNum) #第三步:获取帖子各个楼层的内容 contents=self.getContent(pageNum) #第四步:开始写入文件中 try: self.writedata2File(contents) except IOError,e: print "写入文件发生异常,原因"+e.message finally: print "写入文件完成!"#测试代码如下:#url=raw_input("raw_input:")url="http://www.tieba.baidu.com/p/4197307435"seeLZ=input("input see_lz:")pageNum=input("input pageNum:")floorTag=raw_input("input floorTag:")baidutieba=BaiduTieBa(url,seeLZ,floorTag)#实例化一个对象baidutieba.start(pageNum)#content=baidutieba.getPageContent(pageNum)#调用函数#开始解析得到帖子标题#baidutieba.getPageTitle(1)#开始解析得到帖子的作者#baidutieba.getPageAuthor(1)#baidutieba.getPageTotalPageNum(1)#解析帖子中的内容#baidutieba.getContent(pageNum)

获取代码,可以点击这里:https://github.com/wojiushimogui/get_tiebaContent

参考地址:http://cuiqingcai.com/993.html

分享给朋友:
您可能感兴趣的文章:
随机阅读: