python

导航

python爬虫节点是什么?怎么用?

来源 :中华考试网 2020-11-26

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

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

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

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

  HTML下载器

  #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

  HTML解析器

  #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

  爬虫调度器

  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()

  需要着重说明的是,爬虫节点是分布式爬虫里的一个重要的难点,大家在学习的时候可以多下一些功夫。

分享到

您可能感兴趣的文章