Python 爬虫学习2

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python 爬虫学习2相关的知识,希望对你有一定的参考价值。

这是小白学习笔记....大神勿喷。

本次学习糗事百科的网络爬虫。

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显示出第一次加载的网页段子。

 

 


 

以上是关于Python 爬虫学习2的主要内容,如果未能解决你的问题,请参考以下文章

python爬虫学习笔记-M3U8流视频数据爬虫

全网最全python爬虫系统进阶学习(附原代码)学完可就业

全网最全python爬虫系统进阶学习(附原代码)学完可就业

系统进阶学习python,爬虫,网页设计,正则表达式(附源代码)

学习《从零开始学Python网络爬虫》PDF+源代码+《精通Scrapy网络爬虫》PDF

python 机器学习有用的代码片段