加入收藏 | 设为首页 | 会员中心 | 我要投稿 济南站长网 (https://www.0531zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 运营中心 > 建站资源 > 优化 > 正文

2019 网络爬虫和相关工具

发布时间:2019-06-12 03:26:24 所属栏目:优化 来源:微笑的蚂蚁人
导读:副标题#e# 网络爬虫 网络爬虫(web crawler),以前经常称之为网络蜘蛛(spider),是按照一定的规则自动浏览万维网并获取信息的机器人程序(或脚本),曾经被广泛的应用于互联网搜索引擎。使用过互联网和浏览器的人都知道,网页中除了供用户阅读的文字信息之外,

7.robotparser:解析robots.txt的工具。

  1. >>> from urllib import robotparser 
  2. >>> parser = robotparser.RobotFileParser() 
  3. >>> parser.set_url('https://www.taobao.com/robots.txt') 
  4. >>> parser.read() 
  5. >>> parser.can_fetch('Hellokitty', 'http://www.taobao.com/article') 
  6. False 
  7. >>> parser.can_fetch('Baiduspider', 'http://www.taobao.com/article') 
  8. True 
  9. >>> parser.can_fetch('Baiduspider', 'http://www.taobao.com/product') 
  10. False 

一个简单的爬虫

一个基本的爬虫通常分为数据采集(网页下载)、数据处理(网页解析)和数据存储(将有用的信息持久化)三个部分的内容,当然更为高级的爬虫在数据采集和处理时会使用并发编程或分布式技术,这就需要有调度器(安排线程或进程执行对应的任务)、后台管理程序(监控爬虫的工作状态以及检查数据抓取的结果)等的参与。

2019 网络爬虫和相关工具

一般来说,爬虫的工作流程包括以下几个步骤:

  1. 设定抓取目标(种子页面/起始页面)并获取网页。
  2. 当服务器无法访问时,按照指定的重试次数尝试重新下载页面。
  3. 在需要的时候设置用户代理或隐藏真实IP,否则可能无法访问页面。
  4. 对获取的页面进行必要的解码操作然后抓取出需要的信息。
  5. 在获取的页面中通过某种方式(如正则表达式)抽取出页面中的链接信息。
  6. 对链接进行进一步的处理(获取页面并重复上面的动作)。
  7. 将有用的信息进行持久化以备后续的处理。

下面的例子给出了一个从“搜狐体育”上获取NBA新闻标题和链接的爬虫。

  1. from urllib.error import URLError 
  2. from urllib.request import urlopen 
  3.  
  4. import re 
  5. import pymysql 
  6. import ssl 
  7.  
  8. from pymysql import Error 
  9.  
  10.  
  11. # 通过指定的字符集对页面进行解码(不是每个网站都将字符集设置为utf-8) 
  12. def decode_page(page_bytes, charsets=('utf-8',)): 
  13.     page_html = None 
  14.     for charset in charsets: 
  15.         try: 
  16.             page_html = page_bytes.decode(charset) 
  17.             break 
  18.         except UnicodeDecodeError: 
  19.             pass 
  20.             # logging.error('Decode:', error) 
  21.     return page_html 
  22.  
  23.  
  24. # 获取页面的HTML代码(通过递归实现指定次数的重试操作) 
  25. def get_page_html(seed_url, *, retry_times=3, charsets=('utf-8',)): 
  26.     page_html = None 
  27.     try: 
  28.         page_html = decode_page(urlopen(seed_url).read(), charsets) 
  29.     except URLError: 
  30.         # logging.error('URL:', error) 
  31.         if retry_times > 0: 
  32.             return get_page_html(seed_url, retry_times=retry_times - 1, 
  33.                                  charsets=charsets) 
  34.     return page_html 
  35.  
  36.  
  37. # 从页面中提取需要的部分(通常是链接也可以通过正则表达式进行指定) 
  38. def get_matched_parts(page_html, pattern_str, pattern_ignore_case=re.I): 
  39.     pattern_regex = re.compile(pattern_str, pattern_ignore_case) 
  40.     return pattern_regex.findall(page_html) if page_html else [] 
  41.  
  42.  
  43. # 开始执行爬虫程序并对指定的数据进行持久化操作 
  44. def start_crawl(seed_url, match_pattern, *, max_depth=-1): 
  45.     conn = pymysql.connect(host='localhost', port=3306, 
  46.                            database='crawler', user='root', 
  47.                            password='123456', charset='utf8') 
  48.     try: 
  49.         with conn.cursor() as cursor: 
  50.             url_list = [seed_url] 
  51.             # 通过下面的字典避免重复抓取并控制抓取深度 
  52.             visited_url_list = {seed_url: 0} 
  53.             while url_list: 
  54.                 current_url = url_list.pop(0) 
  55.                 depth = visited_url_list[current_url] 
  56.                 if depth != max_depth: 
  57.                     # 尝试用utf-8/gbk/gb2312三种字符集进行页面解码 
  58.                     page_html = get_page_html(current_url, charsets=('utf-8', 'gbk', 'gb2312')) 
  59.                     links_list = get_matched_parts(page_html, match_pattern) 
  60.                     param_list = [] 
  61.                     for link in links_list: 
  62.                         if link not in visited_url_list: 
  63.                             visited_url_list[link] = depth + 1 
  64.                             page_html = get_page_html(link, charsets=('utf-8', 'gbk', 'gb2312')) 
  65.                             headings = get_matched_parts(page_html, r'<h1>(.*)<span') 
  66.                             if headings: 
  67.                                 param_list.append((headings[0], link)) 
  68.                     cursor.executemany('insert into tb_result values (default, %s, %s)', 
  69.                                        param_list) 
  70.                     conn.commit() 
  71.     except Error: 
  72.         pass 
  73.         # logging.error('SQL:', error) 
  74.     finally: 
  75.         conn.close() 
  76.  
  77.  
  78. def main(): 
  79.     ssl._create_default_https_context = ssl._create_unverified_context 
  80.     start_crawl('http://sports.sohu.com/nba_a.shtml', 
  81.                 r'<a[^>]+test=as[^>]*href=["'](.*?)["']', 
  82.                 max_depth=2) 
  83.  
  84.  
  85. if __name__ == '__main__': 
  86.     main() 

由于使用了MySQL实现持久化操作,所以要先启动MySQL服务器再运行该程序。

(编辑:济南站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!