首页 编程教程正文

【Python】【爬虫实战】re,xpath,BeautifulSoup三种方法爬取古诗词网上诗歌.

piaodoo 编程教程 2020-02-22 22:07:48 915 0 python教程

本文来源吾爱破解论坛

本帖最后由 hustlzp 于 2019-2-15 12:20 编辑

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

附上具体速度:timeit模块

[Python] 纯文本查看 复制代码

timer = timeit.Timer('reParser(text)','from __main__ import reParser,text')
print(timer.timeit(10))
# 0.0378036689999135s

XpathParser(htmltext,goodlist)
timer = timeit.Timer('XpathParser(htmltext,goodlist)','from __main__ import XpathParser,htmltext,goodlist')
#0.17290293400037626

timer = timeit.Timer('bs4Paeser(htmltext,goodlist)','from __main__ import bs4Paeser,htmltext,goodlist')
print(timer.timeit(10))
#2.2884667299986177



下面开始爬取诗词的正题,附上re解析的代码。
[Python] 纯文本查看 复制代码
# 使用正则表达式解析网页元素
# 关键点:直接找每个个体里面相同位置的元素,用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)



爬取的结果如下:
请输入要爬取的页数(1-100):100
陋室铭
唐代:刘禹锡
山不在高,有仙则名。水不在深,有龙则灵。斯是陋室,惟吾德馨。苔痕上阶绿,草色入帘青。谈笑有鸿儒,往来无白丁。可以调素琴,阅金经。无丝竹之乱耳,无案牍之劳形。南阳诸葛庐,西蜀子云亭。孔子云:何陋之有?
有21846人喜欢这首诗(词)哦
**************************************************
元日
宋代:王安石
爆竹声中一岁除,春风送暖入屠苏。千门万户曈曈日,总把新桃换旧符。
有18787人喜欢这首诗(词)哦
**************************************************
关雎
先秦:佚名
关关雎鸠,在河之洲。窈窕淑女,君子好逑。参差荇菜,左右流之。窈窕淑女,寤寐求之。求之不得,寤寐思服。悠哉悠哉,辗转反侧。参差荇菜,左右采之。窈窕淑女,琴瑟友之。参差荇菜,左右芼之。窈窕淑女,钟鼓乐之。
有14859人喜欢这首诗(词)哦
**************************************************
关雎
先秦:佚名
关关雎鸠,在河之洲。窈窕淑女,君子好逑。参差荇菜,左右流之。窈窕淑女,寤寐求之。求之不得,寤寐思服。悠哉悠哉,辗转反侧。参差荇菜,左右采之。窈窕淑女,琴瑟友之。参差荇菜,左右芼之。窈窕淑女,钟鼓乐之。
有14859人喜欢这首诗(词)哦
**************************************************
念奴娇·赤壁怀古
宋代:苏轼
大江东去,浪淘尽,千古风流人物。故垒西边,人道是,三国周郎赤壁。乱石穿空,惊涛拍岸,卷起千堆雪。江山如画,一时多少豪杰。遥想公瑾当年,小乔初嫁了,雄姿英发。羽扇纶巾,谈笑间,樯橹灰飞烟灭。(樯橹 一作:强虏)故国神游,多情应笑我,早生华发。人生如梦,一尊还酹江月。(人生 一作:人间;尊 通:樽)
有12787人喜欢这首诗(词)哦
**************************************************
春日
宋代:朱熹
胜日寻芳泗水滨,无边光景一时新。等闲识得东风面,万紫千红总是春。
有12449人喜欢这首诗(词)哦
**************************************************
观沧海
两汉:曹操
东临碣石,以观沧海。水何澹澹,山岛竦峙。树木丛生,百草丰茂。秋风萧瑟,洪波涌起。日月之行,若出其中;星汉灿烂,若出其里。幸甚至哉,歌以咏志。
有9523人喜欢这首诗(词)哦
**************************************************
游山西村
宋代:陆游
莫笑农家腊酒浑,丰年留客足鸡豚。山重水复疑无路,柳暗花明又一村。箫鼓追随春社近,衣冠简朴古风存。从今若许闲乘月,拄杖无时夜叩门。
有8598人喜欢这首诗(词)哦
**************************************************
行路难·其一
唐代:李白
金樽清酒斗十千,玉盘珍羞直万钱。(羞 通:馐;直 通:值)停杯投箸不能食,拔剑四顾心茫然。欲渡黄河冰塞川,将登太行雪满山。(雪满山 一作:雪暗天)闲来垂钓碧溪上,忽复乘舟梦日边。(碧 一作:坐)行路难!行路难!多歧路,今安在?长风破浪会有时,直挂云帆济沧海。
有8142人喜欢这首诗(词)哦
**************************************************
秋夕
唐代:杜牧
银烛秋光冷画屏,轻罗小扇扑流萤。天阶夜色凉如水,卧看牵牛织女星。(天阶 一作:天街;卧看 一作:坐看)
有7605人喜欢这首诗(词)哦
**************************************************

Xpath版本
[Python] 纯文本查看 复制代码
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)        


bs4版本
[Python] 纯文本查看 复制代码
# 使用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)      

本帖被以下淘专辑推荐: · Python优质笔记整理(学习起来)|主题: 18, 订阅: 112

版权声明:

本站所有资源均为站长或网友整理自互联网或站长购买自互联网,站长无法分辨资源版权出自何处,所以不承担任何版权以及其他问题带来的法律责任,如有侵权或者其他问题请联系站长删除!站长QQ754403226 谢谢。

有关影视版权:本站只供百度云网盘资源,版权均属于影片公司所有,请在下载后24小时删除,切勿用于商业用途。本站所有资源信息均从互联网搜索而来,本站不对显示的内容承担责任,如您认为本站页面信息侵犯了您的权益,请附上版权证明邮件告知【754403226@qq.com】,在收到邮件后72小时内删除。本文链接:https://www.piaodoo.com/7631.html

搜索