python3中数据抓取的三种方法

来源:互联网 发布:什么叫数据流量 编辑:程序博客网 时间:2024/06/02 05:00

1.方法简介
python3中从下载的网页中抓取数据主要的方法有三种,分别是正则表达式、BeautifulSoup、Lxml。三种方法各有特点。
正则表达式,又称规则表达式。(英语:Regular Expression,在代码中常简写为regex、regexp或RE),计算机科学的一个概念。正则表通常被用来检索、替换那些符合某个模式(规则)的文本。
BeautifulSoup是用Python写的一个HTML/XML的解析器,它可以很好的处理不规范标记并生成剖析树(parse tree)。 它提供简单又常用的导航(navigating),搜索以及修改剖析树的操作。它可以大大节省你的编程时间。(安装教程传送门)
Lxml是基于libxml2这一XML 解析库的Python 封装。该模块使用C语言编写, 解析速度比BeautifulSoup 更快, 不过安装过程也更为复杂。

2.性能对比code

import timeimport refrom bs4 import BeautifulSoupimport lxml.htmlfrom urllib import requestdef download(url, user_agent="wsap", num=2):    print("Downloading:"+url)    try:        req = request.Request(url)        req.add_header('user_agent', user_agent)        html = request.urlopen(req).read()    except Exception as e:        print('Download error:')        html = None        if num > 0:            if hasattr(e, "code") and 500 <= e.code < 600:                return download(url, user_agent, num-1)    return htmlFIELDS = ('area', 'population', 'iso', 'country', 'capital', 'continent', 'tld', 'currency_code', 'currency_name', 'phone', 'postal_code_format', 'postal_code_regex', 'languages', 'neighbours')def re_scraper(html):    results = {}    html = html.decode('utf-8')    for field in FIELDS:        results[field] = re.search('<tr id="places_{}__row">.*?<td class="w2p_fw">(.*?)</td>'. format(field), html).groups()[0]    return resultsdef beautiful_soup_scraper(html):    soup = BeautifulSoup(html, 'html.parser')    results = {}    for field in FIELDS:        results[field] = soup.find('table').find('tr', id='places_{}__row'.format(field)).find('td', class_='w2p_fw').text    return resultsdef lxml_scraper(html):    tree = lxml.html.fromstring(html)    results = {}    for field in FIELDS:        results[field] = tree.cssselect('table > tr#places_{}__row > td.w2p_fw'.format(field))[0].text_content()    return resultsNUM_LTERATION = 1000html_copy = download('http://example.webscraping.com/places/default/view/United-Kingdom-239')for name, scraper in [('Regular expressions', re_scraper),                      ('BeautifulSoup', beautiful_soup_scraper),                      ('Lxml', lxml_scraper)]:    start = time.time()    for i in range(NUM_LTERATION):        if scraper == re_scraper:            re.purge()        result = scraper(html_copy)        assert(result['area'] == '244,820 square kilometres')    end = time.time()    print('%s: %.2f seconds' % (name, end - start))

3.运行结果
这里写图片描述

4.结果分析
这里写图片描述
如果你的爬虫瓶颈是下载网页, 而不是抽取数据的话, 那么使用较慢的方法(如BeautifulSoup)也不成问题。如果只需抓取少量数据, 并且想要避免额外依赖的话, 那么正则表达式可能更加适合。不过, 通常情况下, lxml是抓取数据的最好选择, 这是因为该方法既快速又健壮, 而正则表达式和BeautifulSoup只在某些特定场景下有用。