re,xpath ,bs4对同一个页面的解析速度
发现re比xpath快接近10倍,xpath比bs4快接近10倍
可见要想追求极致速度,使用正则表达式解析有多重要

1、re解析的代码

# 使用正则表达式解析网页元素
# 关键点:直接找每个个体里面相同位置的元素,用findall一次提取出来到列表中
import requests
import re
DATA = []
def getHTMLtext(url,headers,timeout=10):
    try :
        resp = requests.get(url,headers=headers,timeout=timeout)
        resp.raise_for_status
        resp.encoding = 'utf-8'
        return resp.text
    except:
        return ''
def reParser(text):
    name_list = re.findall(r'<div class="yizhu".*?<b>(.*?)</b>',text,re.S)  #re.DOTALL
     
    dynasty_list = re.findall(r'<p class="source">.*?target="_blank">(.*?)</a>',text,re.S)
     
    author_list = re.findall(r'<p class="source">.*?target="_blank">.*?</a>.*?target="_blank">(.*?)</a>',text,re.S)
     
    row_content_list = re.findall(r'<div class="contson".*?>(.*?)</div>',text,re.S)
    content_list = []
    for content in row_content_list:
        temp = re.sub(r'<.*?>','',content)  #这里一定要记得不要写成了贪婪匹配哦
        content_list.append(temp.strip()) #去除空格
     
    likes_list = re.findall(r'<span> (\d*?)</span>',text,re.S)
     
    for value in zip(name_list,dynasty_list,author_list,content_list,likes_list):
        name,dynasty,author,content,likes = value
        poetry_dict = {
            '诗词名':name,
            '朝代':dynasty,
            '作者':author,
            '内容':content,
            '点赞数':likes
        }
        DATA.append(poetry_dict)
         
def print_poetry(data):
    for every_poetry in data:
            print(every_poetry['诗词名'])
            print(every_poetry['朝代'] + ':' + every_poetry['作者'] )
            print(every_poetry['内容'])
            print('有{}人喜欢这首诗(词)哦'.format(every_poetry["点赞数"]))
            print("\n"+'*'*50+"\n")
         
if __name__ == '__main__':
    row_url = 'https://www.gushiwen.org/default_{}.aspx'
    headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.109 Safari/537.36'}
    num = input('请输入要爬取的页数(1-100):')
    for i in range(eval(num)):
        url = row_url.format(i+1)
        text = getHTMLtext(url,headers)
        if text == '':
            print('url: {} 访问失败'.format(url))
        else:
            reParser(text)
    DATA.sort(key=lambda x: int(x['点赞数']),reverse = True)
    TOP10 = DATA[:10]
    print_poetry(TOP10) 2、Xpath版本
from lxml import etree
DATA = []
def getHTMLtext(url,headers,timeout=10):
    try :
        resp = requests.get(url,headers=headers,timeout=timeout)
        resp.raise_for_status
        resp.encoding = 'utf-8'
        return resp.text
    except:
        return ''
def xpathParser(text):
    htmlElement = etree.HTML(text)  # <class 'lxml.etree._Element'>
    name_list = htmlElement.xpath('/html/body/div[2]/div[1]/div/div[1]/p[1]/a/b/text()')
    dynasty_list = htmlElement.xpath('/html/body/div[2]/div[1]/div/div[1]/p[2]/a[1]/text()')
    author_list = htmlElement.xpath('/html/body/div[2]/div[1]/div/div[1]/p[2]/a[2]/text()')
    content_list = []
    poetries = htmlElement.xpath('//div[@class="contson" and contains(@id,"contson")]') #返回一个列表,里面每一个都是'lxml.etree._Element'
   # print(etree.tostring(poetries[0],encoding = 'utf-8').decode('utf-8'))
    for poetry in poetries:
        row_content = ''.join(poetry.xpath('.//text()'))#这里的.可千万不能掉,否则会忽略掉poetry哦
        content_list.append(row_content.replace('\n',''))
    row_likes_list = htmlElement.xpath('//a[contains(@id,"agood")]/span/text()') 
    likes_list = [int(like.strip()) for like in row_likes_list]
    for value in zip(name_list,dynasty_list,author_list,content_list,likes_list):
        name,dynasty,author,content,likes = value
        poetry_dict = {
            '诗词名':name,
            '朝代':dynasty,
            '作者':author,
            '内容':content,
            '点赞数':likes
        }
        DATA.append(poetry_dict) 
 
def print_poetry(data):
    for every_poetry in data:
            print(every_poetry['诗词名'])
            print(every_poetry['朝代'] + ':' + every_poetry['作者'] )
            print(every_poetry['内容'])
            print('有{}人喜欢这首诗(词)哦'.format(every_poetry["点赞数"]))
            print("\n"+'*'*50+"\n")
         
if __name__ == '__main__':
    row_url = 'https://www.gushiwen.org/default_{}.aspx'
    headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.109 Safari/537.36'}
    num = input('请输入要爬取的页数(1-100):')
    for i in range(eval(num)):
        url = row_url.format(i+1)
        text = getHTMLtext(url,headers)
        if text == '':
            print('url: {} 访问失败'.format(url))
        else:
            xpathParser(text)
    DATA.sort(key=lambda x: int(x['点赞数']),reverse = True)
    TOP10 = DATA[:10]
    print_poetry(TOP10)
3、bs4版本
# 使用bs4提取网页,先利用find_all解析
import requests
from bs4 import BeautifulSoup
DATA = []
def getHTMLtext(url,headers,timeout=10):
    try :
        resp = requests.get(url,headers=headers,timeout=timeout)
        resp.raise_for_status
        resp.encoding = 'utf-8'
        return resp.text
    except:
        return ''
def bs4_find_all_Parser(text):
    soup = BeautifulSoup(text,'lxml')
    sons = soup.find_all('div',class_ = "sons")[:10] #返回一个<class 'bs4.element.ResultSet'>,每一个元素都是Tag类型
    # 注意:上一步里面返回了一些其他的元素,我们可以提取出前面的10项,那是我们需要用到的
    for son in sons:
        name = son.find('b').string
        print(name)
        dynasty_author = son.find('p',class_="source").get_text()
        print(dynasty_author)
        content = son.find('div',class_="contson").get_text().strip()
        print(content)
        like = son.find_all('span')[1].string.strip()
        print('点赞数:'+like)
        print('\n'+'*'*30+'\n')
         
  
if __name__ == '__main__':
        url = 'https://www.gushiwen.org/default_1.aspx'
        headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.109 Safari/537.36'}
        text = getHTMLtext(url,headers)
        if text == '':
            print('url: {} 访问失败'.format(url))
        else:
            bs4_find_all_Parser(text)

re,xpath,BeautifulSoup三种方法爬取古诗词网上诗歌的更多相关文章

  1. Python学习--两种方法爬取网页图片(requests/urllib)

    实际上,简单的图片爬虫就三个步骤: 获取网页代码 使用正则表达式,寻找图片链接 下载图片链接资源到电脑 下面以博客园为例子,不同的网站可能需要更改正则表达式形式. requests版本: import ...

  2. Pyhton网络爬虫实例_豆瓣电影排行榜_Xpath方法爬取

    -----------------------------------------------------------学无止境------------------------------------- ...

  3. JAVA之线程同步的三种方法

    最近接触到一个图片加载的项目,其中有声明到的线程池等资源需要在系统中线程共享,所以就去研究了一下线程同步的知识,总结了三种常用的线程同步的方法,特来与大家分享一下.这三种方法分别是:synchroni ...

  4. 【SQL】Oracle分页查询的三种方法

    [SQL]Oracle分页查询的三种方法 采用伪列 rownum 查询前10条记录 ? 1 2 3 4 5 6 7 8 9 10 11 [sql] select * from t_user t whe ...

  5. mysql分表的三种方法

    先说一下为什么要分表当一张的数据达到几百万时,你查询一次所花的时间会变多,如果有联合查询的话,我想有可能会死在那儿了.分表的目的就在于此,减小数据库的负担,缩短查询时间.根据个人经验,mysql执行一 ...

  6. Eclipse插件安装的三种方法

    转自:http://www.blogjava.net/tangzurui/archive/2008/06/30/211669.html  整理了一下格式. (前两种安装方式以多国语言包的安装为例) 1 ...

  7. java 获取随机数的三种方法

    方法1(数据类型)(最小值+Math.random()*(最大值-最小值+1))例:(int)(1+Math.random()*(10-1+1))从1到10的int型随数 方法2获得随机数for (i ...

  8. 【转】css清除浮动float的三种方法总结,为什么清浮动?浮动会有那些影响?

    摘要: css清除浮动float的三种方法总结,为什么清浮动?浮动会有那些影响?     一.抛一块问题砖(display: block)先看现象: 分析HTML代码结构: <div class ...

  9. 三种方法实现PCA算法(Python)

    主成分分析,即Principal Component Analysis(PCA),是多元统计中的重要内容,也广泛应用于机器学习和其它领域.它的主要作用是对高维数据进行降维.PCA把原先的n个特征用数目 ...

随机推荐

  1. 数据库中间件之mycat安装部署(一)

    在学习数据库中间件前,我们先抛出三个问题 1.数据库数据量不大,但并发读写操作很大,应该怎么办? 此时我们首先考虑使用缓存中间件来减轻读压力,如果不能满足则考虑数据库读写分离,此时就会引入新的问题,这 ...

  2. (三)easyUI之树形组件

    一.同步树 1.1 概念 所有节点一次性加载完成 1.2 案例 1.2.1 数据库设计 1.2.2 编码 index.jsp <%@ page language="java" ...

  3. (三)SpringBoot之配置文件详解:Properties和YAML

    一.配置文件的生效顺序,会对值进行覆盖: 1. @TestPropertySource 注解 2. 命令行参数 3. Java系统属性(System.getProperties()) 4. 操作系统环 ...

  4. Quartz.net任务调度(石英钟定时任务)

    好了,现在具体来说一下怎么使用Quartz.net 2.0. 1.到网上下载Quartz.net 2.0,下载完后解压,里面有vs.net2008和vs.net2010两个版本. 2.新建一个空项目, ...

  5. JDBC 复习4 批量执行SQL

    1使用jdbc进行批量执行SQL在实际的项目开发中,有时候需要向数据库发送一批SQL语句执行,这时应避免向数据库一条条的发送执行,而应采用JDBC的批处理机制,以提升执行效率. package dbe ...

  6. S2-052

    前言 S2-052的RCE漏洞和以前的有些不同,不再是ognl表达式注入了,而是xml反序列化漏洞导致的RCE(另外还有S2-055漏洞是fastjson的反序列化漏洞).我复现的时候遇到一个坑,导致 ...

  7. Oracle学习笔记——imp还原数据库

    1.     创建用户及指定用户名密码 create user [用户名] identified by [密码]; create user fskxjsxy  identified by fskxjs ...

  8. 将用户赋予sudo权限:配置sudoers文件

    xxx is not in the sudoers file.This incident will be reported.的解决方法   1.切换到root用户下,怎么切换就不用说了吧,不会的自己百 ...

  9. Mysql中的锁机制-转载

    原文:http://blog.csdn.net/soonfly/article/details/70238902 锁是计算机协调多个进程或线程并发访问某一资源的机制.在数据库中,除传统的 计算资源(如 ...

  10. Android 启动流程分析

    原文:https://www.jianshu.com/p/a5532ecc8377 作者曾经在高通的Android性能组工作,主要工作是优化Android Application的启动时间. APP基 ...