xpath re bs4 等爬虫解析器的性能比较

本文原始地址:https://sitoi.cn/posts/23470.html

思路

测试网站地址:http://baijiahao.baidu.com/s?id=1644707202199076031

根据同一个网站,获取同样的数据,重复 500 次取和后进行对比。

测试例子

  1. # -*- coding: utf-8 -*-
  2. import re
  3. import time
  4. import scrapy
  5. from bs4 import BeautifulSoup
  6. class NewsSpider(scrapy.Spider):
  7. name = 'news'
  8. allowed_domains = ['baidu.com']
  9. start_urls = ['http://baijiahao.baidu.com/s?id=1644707202199076031']
  10. def parse(self, response):
  11. re_time_list = []
  12. xpath_time_list = []
  13. lxml_time_list = []
  14. bs4_lxml_time_list = []
  15. html5lib_time_list = []
  16. bs4_html5lib_time_list = []
  17. for _ in range(500):
  18. # re
  19. re_start_time = time.time()
  20. news_title = re.findall(pattern="<title>(.*?)</title>", string=response.text)[0]
  21. news_content = "".join(re.findall(pattern='<span class="bjh-p">(.*?)</span>', string=response.text))
  22. re_time_list.append(time.time() - re_start_time)
  23. # xpath
  24. xpath_start_time = time.time()
  25. news_title = response.xpath("//div[@class='article-title']/h2/text()").extract_first()
  26. news_content = response.xpath('string(//*[@id="article"])').extract_first()
  27. xpath_time_list.append(time.time() - xpath_start_time)
  28. # bs4 html5lib without BeautifulSoup
  29. soup = BeautifulSoup(response.text, "html5lib")
  30. html5lib_start_time = time.time()
  31. news_title = soup.select_one("div.article-title > h2").text
  32. news_content = soup.select_one("#article").text
  33. html5lib_time_list.append(time.time() - html5lib_start_time)
  34. # bs4 html5lib with BeautifulSoup
  35. bs4_html5lib_start_time = time.time()
  36. soup = BeautifulSoup(response.text, "html5lib")
  37. news_title = soup.select_one("div.article-title > h2").text
  38. news_content = soup.select_one("#article").text
  39. bs4_html5lib_time_list.append(time.time() - bs4_html5lib_start_time)
  40. # bs4 lxml without BeautifulSoup
  41. soup = BeautifulSoup(response.text, "lxml")
  42. lxml_start_time = time.time()
  43. news_title = soup.select_one("div.article-title > h2").text
  44. news_content = soup.select_one("#article").text
  45. lxml_time_list.append(time.time() - lxml_start_time)
  46. # bs4 lxml without BeautifulSoup
  47. bs4_lxml_start_time = time.time()
  48. soup = BeautifulSoup(response.text, "lxml")
  49. news_title = soup.select_one("div.article-title > h2").text
  50. news_content = soup.select_one("#article").text
  51. bs4_lxml_time_list.append(time.time() - bs4_lxml_start_time)
  52. re_result = sum(re_time_list)
  53. xpath_result = sum(xpath_time_list)
  54. lxml_result = sum(lxml_time_list)
  55. html5lib_result = sum(html5lib_time_list)
  56. bs4_lxml_result = sum(bs4_lxml_time_list)
  57. bs4_html5lib_result = sum(bs4_html5lib_time_list)
  58. print(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n")
  59. print(f"re 使用时间:{re_result}")
  60. print(f"xpath 使用时间:{xpath_result}")
  61. print(f"lxml 纯解析使用时间:{lxml_result}")
  62. print(f"html5lib 纯解析使用时间:{html5lib_result}")
  63. print(f"bs4_lxml 转换解析使用时间:{bs4_lxml_result}")
  64. print(f"bs4_html5lib 转换解析使用时间:{bs4_html5lib_result}")
  65. print("\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n")
  66. print(f"xpath/re :{xpath_result / re_result}")
  67. print(f"lxml/re :{lxml_result / re_result}")
  68. print(f"html5lib/re :{html5lib_result / re_result}")
  69. print(f"bs4_lxml/re :{bs4_lxml_result / re_result}")
  70. print(f"bs4_html5lib/re :{bs4_html5lib_result / re_result}")
  71. print("\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")

测试结果:

第一次

  1. >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  2. re 使用时间:0.018010616302490234
  3. xpath 使用时间:0.19927382469177246
  4. lxml 纯解析使用时间:0.3410227298736572
  5. html5lib 纯解析使用时间:0.3842911720275879
  6. bs4_lxml 转换解析使用时间:1.6482152938842773
  7. bs4_html5lib 转换解析使用时间:6.744122505187988
  8. >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  9. xpath/re 11.064242408196765
  10. lxml/re 18.934539726245003
  11. html5lib/re 21.336925154218847
  12. bs4_lxml/re 91.51354213550078
  13. bs4_html5lib/re 374.4526223822509
  14. lxml/xpath 1.7113272673976896
  15. html5lib/xpath 1.9284578525152096
  16. >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

第二次

  1. >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  2. re 使用时间:0.023047208786010742
  3. xpath 使用时间:0.18992280960083008
  4. lxml 纯解析使用时间:0.3522317409515381
  5. html5lib 纯解析使用时间:0.418229341506958
  6. bs4_lxml 转换解析使用时间:1.710503101348877
  7. bs4_html5lib 转换解析使用时间:7.1153998374938965
  8. >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  9. xpath/re 8.24059917034769
  10. lxml/re 15.28305419636484
  11. html5lib/re 18.14663742538819
  12. bs4_lxml/re 74.21736476770769
  13. bs4_html5lib/re 308.7315216154427
  14. lxml/xpath 1.8546047296364272
  15. html5lib/xpath 2.2021016979791463
  16. >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

第三次

  1. >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  2. re 使用时间:0.014002561569213867
  3. xpath 使用时间:0.18992352485656738
  4. lxml 纯解析使用时间:0.3783881664276123
  5. html5lib 纯解析使用时间:0.39995455741882324
  6. bs4_lxml 转换解析使用时间:1.751767873764038
  7. bs4_html5lib 转换解析使用时间:7.1871068477630615
  8. >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  9. xpath/re 13.563484360899695
  10. lxml/re 27.022781835827757
  11. html5lib/re 28.56295653062267
  12. bs4_lxml/re 125.10338662716453
  13. bs4_html5lib/re 513.2708620660298
  14. lxml/xpath 1.9923185751389976
  15. html5lib/xpath 2.1058716013241323
  16. >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

结果分析:

三次取平均值结果分析

re xpath lxml html5lib lxml(bs4) html5lib(bs4)
re 1 10.52 19.46 21.84 92.82 382.25
xpath 1 1.85 2.08 8.82 36.34
lxml 1 1.12 4.77 19.64
html5lib 1 4.25 17.50
lxml(bs4) 1 4.12
html5lib(bs4) 1
  • xpath/re :10.52
  • lxml/re :19.46
  • html5lib/re :21.84
  • bs4_lxml/re :92.82
  • bs4_html5lib/re :382.25
  • lxml/xpath :1.85
  • html5lib/xpath :2.08
  • bs4_lxml/xpath :8.82
  • bs4_html5lib/xpath :36.34
  • html5lib/lxml :1.12
  • bs4_lxml/lxml :4.77
  • bs4_html5lib/lxml :19.64
  • bs4_lxml/html5lib :4.25
  • bs4_html5lib/html5lib :17.50
  • bs4_html5lib/bs4_lxml :4.12

三种爬取方式的对比

re xpath bs4
安装 内置 第三方 第三方
语法 正则 路径匹配 面向对象
使用 困难 较困难 简单
性能 最高 适中 最低

结论

re > xpath > bs4

  • re 是 xpath 的 10 倍左右

    虽然 re 在性能上远比 xpath bs4 高很多,但是在使用上,比 xpath 和 bs4 难度上要大很多,且后期维护的困难度上也高很多。

  • xpath 是 bs4 的 1.8 倍左右

    仅仅比较提取的效率来说,xpath 是 bs4 的 1.8 倍左右,但是实际情况还包含 bs4 的 转换过程,在层数多且量大的情况下,实际效率 xpath 要比 bs4 高很多。

总的来说,xpath 加上 scrapy-redis 的分布式已经非常满足性能要求了,建议入 xpath 的坑。

Xpath re bs4 等爬虫解析器的性能比较的更多相关文章

  1. Python HTML解析器BeautifulSoup(爬虫解析器)

    BeautifulSoup简介 我们知道,Python拥有出色的内置HTML解析器模块——HTMLParser,然而还有一个功能更为强大的HTML或XML解析工具——BeautifulSoup(美味的 ...

  2. Jsoup -- 网络爬虫解析器

    需要下载jsoup-1.8.1.jar包 jsoup 是一款Java 的HTML解析器,可直接解析某个URL地址.HTML文本内容.它提供了一套非常省力的API,可通过DOM,CSS以及类似于jQue ...

  3. SQL解析器的性能測试

    对同一个sql语句,使用3种解析器解析出ast语法树(这是编译原理上的说法,在sql解析式可能就是解析器自己定义的statement类型).运行100万次的时间对照. package demo.tes ...

  4. 高性能Java解析器实现过程详解

    如果你没有指定数据或语言标准的或开源的Java解析器, 可能经常要用Java实现你自己的数据或语言解析器.或者,可能有很多解析器可选,但是要么太慢,要么太耗内存,或者没有你需要的特定功能.或者开源解析 ...

  5. 非标准的xml解析器的C++实现:一、思考基本数据结构的设计

    前言: 我在C++项目中使用xml作为本地简易数据管理,到目前为止有5年时间了,从最初的全文搜索标签首尾,直到目前项目中实际运用的类库细致到已经基本符合w3c标准,我一共写过3次解析器,我自己并没有多 ...

  6. python爬虫主要就是五个模块:爬虫启动入口模块,URL管理器存放已经爬虫的URL和待爬虫URL列表,html下载器,html解析器,html输出器 同时可以掌握到urllib2的使用、bs4(BeautifulSoup)页面解析器、re正则表达式、urlparse、python基础知识回顾(set集合操作)等相关内容。

    本次python爬虫百步百科,里面详细分析了爬虫的步骤,对每一步代码都有详细的注释说明,可通过本案例掌握python爬虫的特点: 1.爬虫调度入口(crawler_main.py) # coding: ...

  7. 3 爬虫解析 Xpath 和 BeautifulSoup

    1.正则表达式 单字符: . : 除换行以外所有字符 [] :[aoe] [a-w] 匹配集合中任意一个字符 \d :数字 [-] \D : 非数字 \w :数字.字母.下划线.中文 \W : 非\w ...

  8. Python爬虫——使用 lxml 解析器爬取汽车之家二手车信息

    本次爬虫的目标是汽车之家的二手车销售信息,范围是全国,不过很可惜,汽车之家只显示100页信息,每页48条,也就是说最多只能够爬取4800条信息. 由于这次爬虫的主要目的是使用lxml解析器,所以在信息 ...

  9. 爬虫入门之爬取策略 XPath与bs4实现(五)

    爬虫入门之爬取策略 XPath与bs4实现(五) 在爬虫系统中,待抓取URL队列是很重要的一部分.待抓取URL队列中的URL以什么样的顺序排列也是一个很重要的问题,因为这涉及到先抓取那个页面,后抓取哪 ...

随机推荐

  1. 记一次linux下安装redis, 设置redis服务, 及添加环境变量

    一. redis的安装 cd /opt                                                                                # ...

  2. hzoi欢乐时刻(持续更新)

    %%NC哥 %%Dybala %%cbx吐露(bei ji can)真相 %%skyh×2 不愿透露姓名的群众无意间发现惊人秘密, skyh默默坦白真相, 这究竟是人性的沦丧还是道德的泯灭? %%kx ...

  3. [LeetCode] 785. Is Graph Bipartite? 是二分图么?

    Given an undirected graph, return true if and only if it is bipartite. Recall that a graph is bipart ...

  4. [LeetCode] 394. Decode String 解码字符串

    Given an encoded string, return it's decoded string. The encoding rule is: k[encoded_string], where ...

  5. NOI 2019 退役记

    非常抱歉,因为不退役了,所以这篇退役记鸽了.

  6. 【网络知识之七】QUIC(http3)

    QUIC(Quick UDP Internet Connection)是谷歌制定的一种基于UDP的低时延的互联网传输层协议. 1.避免前序包阻塞HTTP2的最大特性就是多路复用,而HTTP2最大的问题 ...

  7. python 多线程剖析

    先来看个栗子: 下面来看一下I/O秘籍型的线程,举个栗子——爬虫,下面是爬下来的图片用4个线程去写文件 #!/usr/bin/env python # -*- coding:utf-8 -*- imp ...

  8. HTTP之URL的组成部分

    HTTP——URL的组成部分 #################文章全部摘自<HTTP权威指南>########################### 主要是为记录自己学习HTTP的过程! ...

  9. update改数据详解

    update修改数据的要素  : 改哪张表? 改哪几列的值? 分别改成什么值? 在哪些行生效?(这个很重要,否则所有行都会受影响) mysql> update class ; where 表达式 ...

  10. CyclicBarrier一组线程相互等待

    /** * CyclicBarrier 一组线程相互等待 */ public class Beer { public static void main(String[] args) { final ; ...