标签:
这是小白学习笔记....大神勿喷。
本次学习糗事百科的网络爬虫。
http://blog.csdn.net/pleasecallmewhy/article/details/8932310
因为那个糗事百科网页改版了,content类中已经没有title...所以源码也有所改动。
所以找到一个改进版的
http://blog.csdn.net/u011350541/article/details/52264073
感谢以上作者的无私分享。
改进源码:
# -*- coding: utf-8 -*- import urllib2 import urllib import re import thread import time import json #----------- 加载处理糗事百科 ----------- class Spider_Model: def __init__(self): self.page = 1 self.pages = [] self.enable = False # 将所有的段子都扣出来,添加到列表中并且返回列表 def GetPage(self,page): myUrl = "http://m.qiushibaike.com/hot/page/" + page user_agent = ‘Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)‘ headers = { ‘User-Agent‘ : user_agent } req = urllib2.Request(myUrl, headers = headers) myResponse = urllib2.urlopen(req) myPage = myResponse.read() # print myPage unicodePage = myPage.decode("utf-8") # 找出所有class="content"的div标记 #re.S是任意匹配模式,也就是.可以匹配换行符 myItems = re.findall(‘<div.*?class="content">(.*?)</div>‘,unicodePage,re.S) items = [] # print myItems # print str(myItems).decode(‘string_escape‘) # print json.dumps(myItems, encoding="UTF-8", ensure_ascii=False) # for item in myItems: # # item 中第一个是div的标题,也就是时间 # # item 中第二个是div的内容,也就是内容 # items.append([item[0].replace("\n",""),item[1].replace("\n","")]) # print myItems # print str(myItems).decode(‘string_escape‘) # print str(myItems).encode("UTF-8") # print myItems[0] return myItems # 用于加载新的段子 def LoadPage(self): # 如果用户未输入quit则一直运行 while self.enable: # 如果pages数组中的内容小于2个 # print len(self.pages) if len(self.pages) < 2: try: # 获取新的页面中的段子们 myPage = self.GetPage(str(self.page)) self.page += 1 self.pages.append(myPage) except: print ‘无法链接糗事百科!‘ else: time.sleep(5) # def ShowPage(self,nowPage,page): # print u‘第%d页‘ % page,json.dumps(nowPage, encoding="UTF-8", ensure_ascii=False) def ShowPage(self,nowPage,page): i = 0 # print len(nowPage) for i in range(0,len(nowPage)): if i < len(nowPage): print u‘第%d页,第%d个故事‘ %(page,i) ,nowPage[i].replace("\n\n","") i += 1 else: break def Start(self): self.enable = True page = self.page print u‘正在加载中请稍候......‘ # 新建一个线程在后台加载段子并存储 thread.start_new_thread(self.LoadPage,()) #----------- 加载处理糗事百科 ----------- while self.enable: # 如果self的page数组中存有元素 if self.pages: nowPage = self.pages[0] del self.pages[0] self.ShowPage(nowPage,page) page += 1 #----------- 程序的入口处 ----------- print u""" --------------------------------------- 程序:糗百爬虫 版本:0.3 作者:why 日期:2014-06-03 语言:Python 2.7 操作:输入quit退出阅读糗事百科 功能:按下回车依次浏览今日的糗百热点 --------------------------------------- """ print u‘请按下回车浏览今日的糗百内容:‘ raw_input(‘ ‘) myModel = Spider_Model() myModel.Start()
这个源码是可以跑的,但是我跑有点问题。
会出现乱码。
接下来学习并尝试找出原因。
////////////////////////////////////////////////////////////////////////////////////////////
#重新跑了几次后
再跑就不会出现乱码了....好奇怪
但出现了
UnicodeEncodeError: ‘gbk‘ codec can‘t encode character u‘\u22ef‘ in position 13: illegal multibyte sequence
Unhandled exception in thread started by
sys.excepthook is missing
lost sys.stderr
对于这种错误,查了一下,发现
http://www.crifan.com/unicodeencodeerror_gbk_codec_can_not_encode_character_in_position_illegal_multibyte_sequence/
这个帖子讲得很详细。
PS:编码知识
再贴一个讲计算机编码的知乎帖子~
https://www.zhihu.com/question/23374078
讲python编码的帖子
http://lukejin.iteye.com/blog/598303
简而言之:
unicode是信源编码,对字符集数字化;
utf8是信道编码,为更好的存储和传输。
////////////////////////////////////////////////////////////////////////////////////////////
又跑了几次,又出现乱码....
我一步步进行调试,可是却是可以正常运行的,每一页都可以显示出来。
但是跑起来却是正常显示几页后,就乱码了。
不知道为什么....
///////////////////////////////////////////////////////////////////////////////////////////
1.正则表达式
不展开学习,一次性看完会有点乱。
就说一下这个源码里面的。
因为要找出百科里面的段子,所以看了一下网页的html源代码。是这样的。
所以我们就要找<div class = "content">....</div>中间的东西。
就要用到re.findall()
用法:re.findall(pattern, string[, flags]): 返回列表。
举个栗子,eg:
relink为搜索条件
info为搜索目标
然后本次源码如下:
myItems = re.findall(‘<div.*?class="content">(.*?)</div>‘,unicodePage,re.S)
意思就是:
在unicodePage中用‘<div.*?class="content">(.*?)</div>‘这个正则表达式来搜索一切
匹配我们的条件<div class = "content">....</div>的部分,并把搜索结果放进myItems列表中。
2.print的问题
主要针对这条
print u‘第%d页,第%d个故事‘ %(page,i) ,nowPage[i].replace("\n\n","")
%d为占位符,就是先占着一个位置,后面再填充回去。
填充内容就在后面的()里面,就是%d对应page,第二个%d对应 i 。
然后接着输出nowPage[i].replace("\n\n","")
.replace()表示将nowPage[i]里的两个换行符"\n\n"替换成没有东西" "。
这样做的原因是 每行可以显示一则段子。
/////////////////////////////////////////////////////////////////////////////////////
经过调试
大致了解整个源码怎么运行...
后台有一个加载网页的线程LoadPage(),用len(self.pages)是否大于2来进行判断是否加载存储网页,每次只加载一个网页,就是20个段子。
主进程则是显示网页的作用,把第一次加载下来的网页放进列表nowpage里,然后删除self.pages,使它的长度len(self.pages)又回复到1。
接着,后面的线程又可以进行第二次加载,然后在cmd显示出第一次加载的网页段子。
标签:
原文地址:http://www.cnblogs.com/IrisLee/p/5808866.html