原文链接:http://cuiqingcai.com/993.html

划重点:

  1.提取帖子内容时,对图片,贴吧自动增加的超链接,制表符,换行符要做删除或替换处理

  2.decode是把bytes转换为str, encode是把str转换为bytes  原帖中的代码第100行多了一个encode,导致出错

  3.代码中用到了文件相关操作

  4.原文中获取标题的正则表达式我觉得不太对,做了修改。原文只是提取了<h1></h1>直接的,但实际上有在<h3></h3>直接的

最终代码如下,在python3.4.3中实现

import urllib.request
import urllib.parse
import 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 BDTB:
#初始化,传入基地址,是否只看楼主的参数
def __init__(self, baseUrl, seeLZ,floorTag):
self.baseURL = baseUrl
self.seeLZ = '?see_lz='+str(seeLZ)
self.tool = Tool()
self.file = None
self.floor = 1
self.defaultTitle = u"百度贴吧"
self.floorTag = floorTag
#传入页码,获取该页帖子的代码
def getPage(self, pageNum):
try:
url = self.baseURL+self.seeLZ+'&pn='+str(pageNum)
request = urllib.request.Request(url)
response = urllib.request.urlopen(request)
return response.read().decode('utf-8','ignore') #注意转换成字符串
except urllib.error.URLError as e:
if hasattr(e, "reason"):
print(u"连接百度贴吧失败,错误原因:", e.reason)
return None
#获取帖子标题
def getTitle(self):
pageCode = self.getPage(1)
pattern = re.compile('''<h\d class="core_title_txt.*?title="(.*?)" style="width:.*?</h\d>''', re.S)
result = re.search(pattern, pageCode)
if result:
title = result.group(1).strip() #这里注意,获取分组的方法
return title
else:
return None #提取帖子页数
def getPageNum(self):
pageCode = self.getPage(1)
pattern = re.compile('''<span class=.*?</span>.*?回复贴,共.*?<span class=.*?>(.*?)</span>''', re.S)
result = re.search(pattern, pageCode)
if result:
pageNum = result.group(1).strip()
return pageNum
else:
return None #获取每一层楼的内容,传入页面内容
def getContent(self, page):
pattern = re.compile('<div id="post_content_.*?>(.*?)</div>',re.S)
items = re.findall(pattern, page)
contents = []
for item in items:
content = "\n"+self.tool.replace(item)+"\n"
contents.append(content)
return contents def setFileTitle(self, title):
if title is not None:
self.file = open(title+".txt","w+")
else:
self.file = open(self.defaultTitle+".txt","w+") def writeData(self, contents):
#向文件写入每一楼的信息
for item in contents:
if self.floorTag == '':
#楼之间的分隔符
floorLine = "\n" + str(self.floor) + "楼-------------------------------------"
self.file.write(floorLine)
self.file.write(item)
self.floor+=1 def start(self):
pageNum = self.getPageNum()
title = self.getTitle()
self.setFileTitle(title)
if pageNum == None:
print(u"URL已失效,请重试")
return
try:
print("该帖子共有" + str(pageNum) + "页")
for i in range(1, int(pageNum) + 1):
print("正在写入第"+str(i)+"页数据")
page = self.getPage(i)
contents = self.getContent(page)
self.writeData(contents)
#出现写入异常
except IOError as e:
print("写入异常,原因"+e.message)
finally:
print("写入任务完成") print(u"请输入帖子代号")
baseURL = 'http://tieba.baidu.com/p/' + str(input(u'http://tieba.baidu.com/p/'))
seeLZ = input("是否只看楼主发言,是输入1,否输入0\n")
floorTag = input("是否写入楼层信息,是输入1,否输入0\n")
bdtb = BDTB(baseURL, seeLZ, floorTag)
bdtb.start()

【python】抄写大神的百度贴吧代码的更多相关文章

  1. 【python】抄写大神的糗事百科代码

    照着静觅大神的博客学习,原文在这:http://cuiqingcai.com/990.html 划重点: 1. str.strip() strip函数会把字符串的前后多余的空白字符去掉 2. resp ...

  2. 厉害了,Google大神每天写多少行代码?

    文章转自开源中国社区,编译自:Quora Quora上有个有趣的问题:Google工程师们每天写多少行代码? Google 的 AdMob 全栈工程师 Raymond Farias 在 Quora 发 ...

  3. 90%的人说Python程序慢,5大神招让你的代码像赛车一样跑起来

    1.for 循环 我们大部分的时候代码里面都有for循环,然后里面嵌套一段逻辑处理,下面有两种方法来完成: 二者的性能差距有多大呢,一般我们用内置的timeit模块来量化比较: 把传统的for改成推导 ...

  4. Python:大神用的贼溜的实用技巧分享

    整理字符串输入 整理用户输入的问题在编程过程中极为常见.通常情况下,将字符转换为小写或大写就够了,有时你可以使用正则表达式模块「Regex」完成这项工作.但是如果问题很复杂,可能有更好的方法来解决: ...

  5. [python] 求大神解释下 面向对象中方法和属性

    面向对象中 类方法 实例方法 类属性 实例属性该如何理解呢?

  6. “使用多target来构建大量相似App”,唐巧大神理论验证(附工程代码地址)

    无意间看到巧神的文章时,感觉非常兴奋,此文章正好解决了公司目前项目的痛点. 读到以下关键一段时,不甚明了,故自己做了实验分享给有缘人. "我们的每个课程的资源文件都具有相同的文件名,例如首页 ...

  7. 大神:python怎么爬取js的页面

    大神:python怎么爬取js的页面 可以试试抓包看看它请求了哪些东西, 很多时候可以绕过网页直接请求后面的API 实在不行就上 selenium (selenium大法好) selenium和pha ...

  8. VsCode写Python代码!这代码简直和大神一样规范!太漂亮了!

    VsCode写Python代码!这代码简直和大神一样规范!太漂亮了!    转 https://www.jianshu.com/p/636306763d89 VsCode虽然没有Pycharm的功能齐 ...

  9. python从入门到大神---Python的jieba模块简介

    python从入门到大神---Python的jieba模块简介 一.总结 一句话总结: jieba包是分词技术,也就是将一句话分成多个词,有多种分词模型可选 1.分词模块包一般有哪些分词模式(比如py ...

随机推荐

  1. redis基础和通用key操作

    redis是什么? redis开源的,构建于内存的数据结构的nosql数据库.常被用于数据存储,缓存处理和消息处理. redis的优势? 1.极高的读写能力 2.丰富的数据类型 3.原子性操作 4.支 ...

  2. POJ 2135 Farm Tour(最小费用最大流)

    Description When FJ's friends visit him on the farm, he likes to show them around. His farm comprise ...

  3. C++STL——set

    一.相关定义 set 集合,有唯一性,即每一个元素只有一个: 是一个有序的容器,里面的元素都是排序好的: 支持插入,删除,查找等操作. 注意 set中的元素可以是任意类型的,但是由于需要排序,所以元素 ...

  4. 将EXCEL表中的数据轻松导入Mysql数据表

    转载自:http://blog.163.com/dielianjun@126/blog/static/164250113201042310181431/ 在网络上有不较多的方法,在此介绍我已经验证的方 ...

  5. 最小生成树(MST)

    原创 今天来说说最小生成树问题,我们知道最小生成树有两种求法,一种是prim算法,另一种是kruskal算法,关于两种算法的定义以及证明,请查看相关资料,这里不多说,理解起来也相当容易,我们来看一个问 ...

  6. microtime()

    PHP函数microtime()返回当前 Unix 时间戳和微秒数.

  7. 猜数字(C语言版)

    编程先由计算机“想”一个1到100之间的数请人猜,如果人猜对了,则结束游戏,并在屏幕上输出人猜了多少次才猜对此数,以此来反映猜数者“猜”的水平,否则计算机给出提示,告诉人所猜的数是太大还是太小,最多可 ...

  8. PHP的报错级别并返回当前级别error_reporting()

    定义和用法:error_reporting() 设置 PHP 的报错级别并返回当前级别.函数语法:error_reporting(report_level) 如果参数 level 未指定,当前报错级别 ...

  9. DataBase -- JOIN

    SQL JOIN:用于根据两个或多个表中列的关系,从这些表中查数据. (为了得到完整数据,我们需要从两个或多个表中获取结果.) 例如W3School中列出的实例,使用如下语句: select Pers ...

  10. PowerShell收发TCP消息包

    PowerShell收发TCP消息包 https://www.cnblogs.com/fuhj02/archive/2012/10/16/2725609.html 在上篇文章中,我们在PSNet包中创 ...