吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 8151|回复: 15
收起左侧

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

  [复制链接]
hustlzp 发表于 2019-2-14 20:51
本帖最后由 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)      

免费评分

参与人数 5吾爱币 +7 热心值 +5 收起 理由
ke307 + 1 + 1 我很赞同!
huguo002 + 1 + 1 我很赞同!
kofdy + 1 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
苏紫方璇 + 3 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
山治c + 1 + 1 热心回复!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

null119 发表于 2019-2-28 11:15
dreamrise 发表于 2019-2-28 10:01
求教下楼主,对这个网站的具体每首诗,如果想获取它的注释和译文,要怎么实现。
比如:
https://so.gushi ...

F12看一下就知道了,
注释译文地址:https://so.gushiwen.org/shiwen2017/ajaxfanyi.aspx?id=XXXX
XXXX在页面源码中搜索一下href="javascript:fanyiShow,在后面的括号里就是这个id
以你给的地址为例:https://so.gushiwen.org/shiwenv_30a67e5c53be.aspx
1、获取页面源码得到id为2141
2、直接GET地址:https://so.gushiwen.org/shiwen2017/ajaxfanyi.aspx?id=2141即可获取注释译文内容了

免费评分

参与人数 1吾爱币 +3 热心值 +1 收起 理由
hustlzp + 3 + 1 我很赞同!

查看全部评分

yth492300648 发表于 2019-2-14 21:12
m9999m1 发表于 2019-2-14 22:24
dreamrise 发表于 2019-2-28 10:01
求教下楼主,对这个网站的具体每首诗,如果想获取它的注释和译文,要怎么实现。
比如:
https://so.gushiwen.org/shiwenv_30a67e5c53be.aspx
这首诗,直接进去后,注释和译文不是完全展示出来的,需要点击“展开阅读全文”,才会完全显示。
这个用上面的三种方式怎么实现?

点评

F12看一下就知道了, 注释译文地址:https://so.gushiwen.org/shiwen2017/ajaxfanyi.aspx?id=XXXX XXXX在页面源码中搜索一下href="javascript:fanyiShow,在后面的括号里就是这个id 以你给的地址为例:https://so  详情 回复 发表于 2019-2-28 11:15
 楼主| hustlzp 发表于 2019-2-28 11:07
dreamrise 发表于 2019-2-28 10:01
求教下楼主,对这个网站的具体每首诗,如果想获取它的注释和译文,要怎么实现。
比如:
https://so.gushi ...

分为两步实现
1. 先在列表页(比如https://www.gushiwen.org/shiwen/)获取每一个诗歌的详情页的url,将其放到一个list里面
2. 对每一个List的url,设置一个parse函数进行解析
dreamrise 发表于 2019-2-28 14:31
null119 发表于 2019-2-28 11:15
F12看一下就知道了,
注释译文地址:https://so.gushiwen.org/shiwen2017/ajaxfanyi.aspx?id=XXXX
XXXX ...

嗯嗯,这个方案不错。

之前找到了这个地址,但是都没去试一下。没想到直接是译文和注释。
newpowersky 发表于 2019-2-28 16:02
null119 发表于 2019-2-28 11:15
F12看一下就知道了,
注释译文地址:https://so.gushiwen.org/shiwen2017/ajaxfanyi.aspx?id=XXXX
XXXX ...

爬这个网站不错,可以知道不少诗
石林 发表于 2019-5-17 17:41
爬这个网站不错,可以知道不少诗
Kaiter_Plus 发表于 2019-5-18 17:28
感谢楼主分享!学习一下!
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-16 15:40

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表