zoukankan      html  css  js  c++  java
  • 使用python多线程实现一个简单spider

    老习惯,先看看别人的工作。推荐看看 我的知识库(1)--Java 搜索引擎的实现— 网络爬虫 文章把相关概念讲的很详细了。

    老样子,我也是初学者,通过本次学习主要掌握以下几点:

    1.了解python 网络编程

    2.了解python多线程锁机制

    3.掌握python re模块match使用

    那么开始吧

    1.使用python抓取一个网页的内容

    使用urllib模块

    1 def getWebPage(url):
    2     wp = urllib.urlopen(url)
    3     content = wp.read()
    4     return content

    2.对抓取到的网页内容进行分析,提取有用URL
    抓到的数据是用str存储的,下面使用python里的re.split()和re.match()

    1 def analysisPage(content):
    2     strlist = re.split('\"',content)
    3     urlset = set([])
    4     for str in strlist:
    5         if re.match('http://www.cnblogs.com(/|\w)+', str):
    6                 urlset.add(str + '\n')
    7     return list(urlset)

    园里关于python的html解析的文章很多,看的我眼花缭乱,这里就不一一列举了。

    这里有个问题,我把match里的pattern改成 ’http://www.cnblogs.com(/|\w)+html$' 就

    匹配不出结果了,不知道什么原因,哪位大神知道。

    3.多线程

    主要用了一个urllist和一个urlset。

    urlset用来存储已经访问过的网页url,urllist用来存储待访问的网页url

    申请四个线程并行的对urllist的url进行页面抽取,提取页面url加入到urllist中

    为了互斥使用urllist和urlset,引入了listlock和setlock两把锁

    全部代码如下:

     1 import re
     2 import urllib
     3 import threading
     4 
     5 def getWebPage(url):
     6     wp = urllib.urlopen(url)
     7     content = wp.read()
     8     return content
     9 
    10 def analysisPage(content, urllist, urlset):
    11     strlist = re.split('\"',content)
    12     geturlset = set([])
    13     for str in strlist:
    14         if re.match('http://www.cnblogs.com/(/|\w)+', str):
    15             geturlset.add(str + '\n')
    16 
    17     setlock.acquire()
    18     geturlset = geturlset - urlset
    19     setlock.release()
    20 
    21     listlock.acquire()
    22     for url in list(geturlset):
    23         urllist.append(url)
    24     listlock.release()
    25 
    26 class MyThread(threading.Thread):
    27     def __init__(self, urllist, urlset):
    28         threading.Thread.__init__(self)
    29         self.urllist = urllist
    30         self.urlset = urlset
    31 
    32     def run(self):
    33         while True:
    34             listlock.acquire()
    35             if self.urllist:
    36                 url = self.urllist.pop(0)
    37                 listlock.release()
    38             else:
    39                 listlock.release()
    40                 break
    41 
    42             setlock.acquire()
    43             if len(self.urlset) >= 50:
    44                 setlock.release()
    45                 break
    46             else:
    47                 if url in self.urlset:
    48                     setlock.release()
    49                     continue
    50                 else:
    51                     self.urlset.add(url)
    52                     setlock.release()
    53                     content = getWebPage(url)
    54                     analysisPage(content, self.urllist, self.urlset)
    55 
    56 listlock = threading.RLock()
    57 setlock = threading.RLock()
    58 
    59 if __name__ == '__main__':
    60     starturl = 'http://www.cnblogs.com/\n'
    61     content = getWebPage(starturl)
    62     #urlset存放已访问过的网页url
    63     #urllist存放待访问的网页url
    64     urlset = set([starturl])
    65     urllist = []
    66     analysisPage(content, urllist, urlset)    
    67     tlist = []
    68     for i in range(4):
    69         t = MyThread(urllist, urlset)
    70         t.start()
    71         tlist.append(t)
    72     for t in tlist:
    73         t.join()
    74     f = open('url.txt', 'w')
    75     f.writelines(list(urlset))
    76     f.close()

    当urlset集合的元素超过50时就停止,当这个数值较大时,socket会出问题,我也不知道什么原因,应该和网络有关。

  • 相关阅读:
    《SQL Server 2008从入门到精通》--20180628
    2019国赛
    [蓝桥杯2020] 湖北省省赛
    2019第十届蓝桥杯B组决赛题解第五题
    试题 算法提高 分解质因数
    大数相加减
    试题 算法提高 汉诺塔
    试题 算法提高 欧拉函数
    试题 算法提高 天天向上-dp
    算法训练 猴子吃包子-构造
  • 原文地址:https://www.cnblogs.com/2010Freeze/p/2567389.html
Copyright © 2011-2022 走看看