返回介绍

7.3 爬虫节点

发布于 2024-01-26 22:39:51 字数 4785 浏览 0 评论 0 收藏 0

爬虫节点(SpiderNode)相对简单,主要包含HTML下载器、HTML解析器和爬虫调度器。执行流程如下:

·爬虫调度器从控制节点中的url_q队列读取URL。

·爬虫调度器调用HTML下载器、HTML解析器获取网页中新的URL和标题摘要。

·爬虫调度器将新的URL和标题摘要传入result_q队列交给控制节点。

7.3.1 HTML下载器

HTML下载器的代码和第6章的一致,只要注意网页编码即可。代码如下:

  # coding:utf-8
  import requests
  class HtmlDownloader(object):
  
     def download(self,url):
       if url is None:
            return None
       user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'
       headers={'User-Agent':user_agent}
       r = requests.get(url,headers=headers)
       if r.status_code==200:
            r.encoding='utf-8'
            return r.text
       return None

7.3.2 HTML解析器

HTML解析器的代码和第6章的一致,详细的网页分析过程可以回顾第6章。代码如下:

  # coding:utf-8
  import re
  import urlparse
  from bs4 import BeautifulSoup
  
  
  class HtmlParser(object):
  
     def parser(self,page_url,html_cont):
       '''
       用于解析网页内容,抽取URL和数据
       :param page_url: 下载页面的URL
       :param html_cont: 下载的网页内容
       :return:返回URL和数据
       '''
       if page_url is None or html_cont is None:
            return
       soup = BeautifulSoup(html_cont,'html.parser',from_encoding='utf-8')
       new_urls = self._get_new_urls(page_url,soup)
       new_data = self._get_new_data(page_url,soup)
       return new_urls,new_data
  
  
     def _get_new_urls(self,page_url,soup):
       '''
       抽取新的URL集合
       :param page_url: 下载页面的URL
       :param soup:soup
       :return: 返回新的URL集合
       '''
       new_urls = set()
       # 抽取符合要求的a标记
       links = soup.find_all('a',href=re.compile(r'/view/\d+\.htm'))
       for link in links:
            # 提取href属性
            new_url = link['href']
            # 拼接成完整网址
            new_full_url = urlparse.urljoin(page_url,new_url)
            new_urls.add(new_full_url)
       return new_urls
     def _get_new_data(self,page_url,soup):
       '''
       抽取有效数据
       :param page_url:下载页面的URL
       :param soup:
       :return:返回有效数据
       '''
       data={}
       data['url']=page_url
       title = soup.find('dd',class_='lemmaWgt-lemmaTitle-title').find('h1')
       data['title']=title.get_text()
       summary = soup.find('div',class_='lemma-summary')
       # 获取tag中包含的所有文本内容,包括子孙tag中的内容,并将结果作为Unicode字符串返回
       data['summary']=summary.get_text()
       return data

7.3.3 爬虫调度器

爬虫调度器需要用到分布式进程中工作进程的代码,具体内容可以参考第1章的分布式进程章节。爬虫调度器需要先连接上控制节点,然后从url_q队列中获取URL,下载并解析网页,接着将获取的数据交给result_q队列并返回给控制节点,代码如下:

  class SpiderWork(object):
     def __init__(self):
       # 初始化分布式进程中工作节点的连接工作
       # 实现第一步:使用BaseManager注册用于获取Queue的方法名称
       BaseManager.register('get_task_queue')
       BaseManager.register('get_result_queue')
       # 实现第二步:连接到服务器
       server_addr = '127.0.0.1'
       print('Connect to server %s...' % server_addr)
       # 注意保持端口和验证口令与服务进程设置的完全一致
       self.m = BaseManager(address=(server_addr, 8001), authkey='baike')
       # 从网络连接
       self.m.connect()
       # 实现第三步:获取Queue的对象
       self.task = self.m.get_task_queue()
       self.result = self.m.get_result_queue()
       # 初始化网页下载器和解析器
       self.downloader = HtmlDownloader()
       self.parser = HtmlParser()
       print 'init finish'
  
     def crawl(self):
       while(True):
            try:
              if not self.task.empty():
                url = self.task.get()
  
                if url =='end':
                     print '控制节点通知爬虫节点停止工作...'
                     # 接着通知其他节点停止工作
                     self.result.put({'new_urls':'end','data':'end'})
                     return
                print '爬虫节点正在解析:%s'%url.encode('utf-8')
                content = self.downloader.download(url)
                new_urls,data = self.parser.parser(url,content)
                self.result.put({"new_urls":new_urls,"data":data})
            except EOFError,e:
              print "连接工作节点失败"
              return
            except Exception,e:
              print e
              print 'Crawl  fali '
  
  if __name__=="__main__":
     spider = SpiderWork()
     spider.crawl()

在爬虫调度器中设置了一个本地IP 127.0.0.1,大家可以在一台机器上测试代码的正确性。当然也可以使用三台VPS服务器,两台运行爬虫节点程序,将IP改为控制节点主机的公网IP,一台运行控制节点程序,进行分布式爬取,这样更贴近真实的爬取环境。图7-3为最终爬取的数据,图7-4为new_urls.txt的内容,图7-5为old_urls.txt的内容,大家可以进行对比测试,这个简单的分布式爬虫还有很大的发挥空间,希望大家发挥自己的聪明才智进一步完善。

图7-3 最终爬取的数据

图7-4 new_urls.txt

图7-5 old_urls.txt

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文