python 爬虫实战 抓取学校bbs相关板块的发帖信息
来源:互联网 发布:tv电影软件 编辑:程序博客网 时间:2024/06/05 06:52
1. 前言
之前也因为感兴趣, 写过一个抓取桌面天空里面喜欢的动漫壁纸的爬虫代码。这两天突然看到有人写了这么一篇文章: 爬取京东本周热卖商品基本信息存入MySQL
觉得蛮有趣的, 正好临近找工作的季节, 就想着能不能写个爬虫, 把咱们学校bbs上面相关的板块里面的发帖信息给记录下来。
2. 项目分析
- 首先我们打开我们的目标网页http://bbs.ustc.edu.cn/main.html
结果我们发现, 进入到job板块之后, 还是没有找到网页的源码信息,ie, 我们没有找到他的真正的网页地址。我们一开始猜想我们的bbs 应该是使用post方式, 利用js 异步获取网页数据的, 然而, 当我们进入Network功能查看的时候, 发现他实际上还是使用了 GET 方式, 只不过他的真实地址被隐藏了而已
上面用红框框圈出来的地址就是Job 板块的真实地址了
然后我们就可以方便的找到我们的真实地址以及网页源码了
由于, 我们学校的bbs上面回帖信息一般都不咋地, 于是这里, 我们直接忽略他
得到不含回帖信息的url
http://bbs.ustc.edu.cn/cgi/bbsbfind?type=1&board=Job&title=&title2=&title3=&userid=&dt=7&og=on&boardordigest=0&labelabc=0
我们发现真正需要变化的是 Job 部分, 将Job 改成 Intern 可以得到实习板块的相关信息。
然后我们查看网页的源码:
由于我们需要得到作者, 日期, 帖子的连接地址, 标题 这四个信息, 很容易分析得到我们所需要使用的正则表达式:
string = "author.*?><a.*?>(.*?)</a>.*?datetime.*?>(.*?)<.*?title.*?<a.*?=(.*?)>(.*?)</a>"
其中第三项得到我们帖子的相应地址, 同样可以分析得到提取帖子内容的正则表达式为:
pattern_str = "WWWPOST(.*?)<br/>--"
至此, 基本分析完毕
3. 编写过程中遇到的一些坑
- 在re.findall 的地方, 发生假死
- 这个里面具体原因在于我们的正则表达式没有能够一开始就匹配成功, 导致进入死循环, 修正正则表达式即可
- 中文字节码输出u’\u5357\u4eac\u5fb7\u552f\u601d\u7eba\u7ec7\u54c1
- 这个并不是错误, 但是很讨厌, 他只是输出字节码, 而且这个现象时有时无, 在出现这个问题的时候, 我们可以在相应的 str 后面加上
decode("utf−8") 即可正常输出中文了
- 这个并不是错误, 但是很讨厌, 他只是输出字节码, 而且这个现象时有时无, 在出现这个问题的时候, 我们可以在相应的 str 后面加上
UnicodeDecodeError:‘XXX’ codec can’t decode bytes in position错误信息解 决办法
- http://www.imleon.cn/unicodedecodeerrorxxx-in-the-python-codec-cant-decode-bytes-in-position-error-solution.html 这篇文章中提到,
inStr2=inStr.decode(‘utf−8',‘ignore′) 加一个ignore 参数就可以了
- http://www.imleon.cn/unicodedecodeerrorxxx-in-the-python-codec-cant-decode-bytes-in-position-error-solution.html 这篇文章中提到,
UnicodeEncodeError: ‘ascii’ codec can’t encode characters in position。。
解决方法
有两种办法可以解决1.换成python 3.x2.在代码前面加上import sysreload(sys)sys.setdefaultencoding('utf-8')
cmd 窗口大小调节
- cmd 窗口乱码问题
我们的代码在eclipse 的console 中正常显示, 但是到了cmd中就中文乱码了, 这里的解决方案是: 将输出字符全部encode 成 gb2312
4. 运行效果
5. code
# -*- coding:utf-8 -*-'''Created on 2016-5-2获取 BBS 相关板块的信息@author: ThinkPad User'''import sys reload(sys) sys.setdefaultencoding('utf8') import urllibimport urllib2import reclass BBSSpider: ''' classdocs ''' def __init__(self): #self.baseURL = "http://bbs.ustc.edu.cn/cgi/bbsdoc?board=" + str(board) self.baseURL = "" self.enable = True self.charaterset = "gb2312" # 获取最近不含回帖的帖子 def getHtml(self, url): #self.baseURL = "http://bbs.ustc.edu.cn/cgi/bbsbfind?type=1&board=" + str(board) + "&title=&title2=&title3=&userid=&dt=7&og=on&boardordigest=0&labelabc=0" self.baseURL = url try: request = urllib2.Request(self.baseURL) response = urllib2.urlopen(request) #print response.read().decode(self.charaterset, 'ignore') return response.read().decode("gb2312", 'ignore').encode("utf-8") except urllib2.URLError, e: if hasattr(e, "reason"): string = "连接bbs 失败, 原因" + str(e.reason) print string.encode(self.charaterset) return None # 删除 获取的网页内容中的一些噪声 def removeNoise(self, content): # 去除 removeNBSP = re.compile(r" ") content = re.sub(removeNBSP, " ", content).strip() removeAMP = re.compile(r"&") content = re.sub(removeAMP, "&", content).strip() removeBR = re.compile(r"<br/>") content = re.sub(removeBR, "\n", content).strip() # remove blank line removeN = re.compile(r"\n{1,}") content = re.sub(removeN, "\n", content).strip() return content # 获取发帖信息 def getItem(self, board): string = "http://bbs.ustc.edu.cn/cgi/bbsbfind?type=1&board=" + str(board) + "&title=&title2=&title3=&userid=&dt=7&og=on&boardordigest=0&labelabc=0" content = self.getHtml(string) if not content: print "加载页面失败" return #string = r"author.*?><a.*?>(.*?)</a>.*?datetime.*?>(.*?)<.*?title><a.*?>(.*?)</a>" string = r"author.*?><a.*?>(.*?)</a>.*?datetime.*?>(.*?)<.*?title.*?<a.*?=(.*?)>(.*?)</a>" pattern = re.compile(string, re.S) res = re.findall(pattern, content) stories = [] count = 0 for item in res: text = self.removeNoise(item[3]) stories.append(item[2]) # 获取内容 string_out = str("id:%3d\t发帖人:%20s\t发帖时间:%20s\t发帖标题:%40s" % (count, item[0], item[1], text)) print string_out.encode(self.charaterset) count += 1 return stories # 获取详细信息 def getDetails(self, board): stories = self.getItem(board) if not stories: return total_num = len(stories) while self.enable: string_tip = str("\n\n================【请输入需要查看的帖子的id, 按 Q 退出】==============").encode(self.charaterset) id = raw_input(string_tip) if id == "Q": self.enable = False break try: int_id = int(id) if int_id < 0 or int_id >= total_num: continue except: continue string = "http://bbs.ustc.edu.cn/cgi/" + stories[int_id] content = self.getHtml(string) if not content: print "获取网页信息失败" return pattern_str = "WWWPOST(.*?)<br/>--" pattern = re.compile(pattern_str, re.S) res = re.findall(pattern, content) for item in res: text = self.removeNoise(item) print text.encode(self.charaterset) # 使用常用板块信息 def getBoard(self): flag = True self.enable = True boards = ['Job', 'Intern', 'SecondHand', 'PieBridge', 'Free', 'PMPI', 'Badminton', 'Swimming'] count = 0 for item in boards: print "id:%d board:%15s" % (count, boards[count]) count += 1 total_num = count while flag: self.enable = True string_tip = str("\n\n===================【请输入需要查看的板块的id, 按 Q 退出】================").encode(self.charaterset) id = raw_input(string_tip) if id == "Q": flag = False break try: int_id = int(id) if int_id < 0 or int_id >= total_num: continue except: continue self.getDetails(boards[int_id])if "__main__" == __name__: bbs = BBSSpider() bbs.getBoard() #bbs.getDetails("Job")
0 0
- python 爬虫实战 抓取学校bbs相关板块的发帖信息
- Python爬虫实战---抓取图书馆借阅信息
- python 爬虫实战--登陆学校教务系统获取成绩信息
- Python爬虫实战三 | 蓝奏网盘抓取网盘链接信息
- python 爬虫 实战(一) —— 抓取学校开课数据
- python实现爬虫统计学校BBS男女比例(三)数据处理
- python实现爬虫统计学校BBS男女比例(三)数据处理
- Python爬虫学习,抓取网页上的天气信息
- python实现爬虫统计学校BBS男女比例(二)多线程爬虫
- python实现爬虫统计学校BBS男女比例(二)多线程爬虫
- Python爬虫实战一之使用Beautiful Soup抓取百度招聘信息并存储excel文件
- python 爬虫 实战 抓取妹子图中图
- Python爬虫实战 抓取淘宝照片
- Python爬虫实战:抓取淘宝MM照片
- Python爬虫实战:抓取淘宝MM照片
- python 爬虫抓取19楼租房信息
- [python][project][爬虫] 时光网抓取信息
- php爬虫抓取信息及反爬虫相关
- 图像处理中的卷积总结
- Drawable资源——StateListDrawable 资源
- 手把手教你把Vim改装成一个IDE编程环境(图文)
- 微信公众平台开发入门教程
- OC 函数库方法
- python 爬虫实战 抓取学校bbs相关板块的发帖信息
- Game of Throne S04E02 POV:Bran
- 1、关于多个html标签单击事件的实现细节
- 【bzoj2049】[Sdoi2008]Cave 洞穴勘测
- Light 1387-Setu
- [笔记] Node-Link可视化图中移动Node后自动布局调整算法
- TensorFlow教程02:针对机器学习初学者的MNIST实验——Softmax回归
- 穿过街道(递归OR递推)(搜索)
- Mysql 特殊字符转义问题