Python爬虫爬取百度汉语的古诗词

前言

谁能想到一个我写这玩意只是为了应付语文作业,写下这篇博文主要是记录一下我的艰难的探索过程(哭)

正文

爬虫啊,用Python写真是再舒♂服不过了

在coding之前,我们先来了解一下selenium与BeautifulSoup

selenium

selenium是一个用于Web应用程序测试的工具,它可以像真正的用户操作一样,直接运行浏览器。我们将用它来获取百度古文的网页

Q:直接用requests不就行了吗?

A:百度古文是动态网页,你发http请求的时候,古诗文还没加载出来呢!,所以我们得用selenium的WebDriverWait去等待网页加载好。

BeautifulSoup

这个名字应该出自于《爱丽丝梦游仙境》,毕竟其官网的插图于测试文本都是来自于《爱丽丝梦游仙境》,你可以叫它“美丽的汤”(笑),它可以用来解析网页,用起来比正则容易得多。

网页分析

先在百度汉语中搜索
image.png
看到url的变化了没?不难看出,我们只需要改变wd的值就可以得到相应的网页了
image.png

Code

def getpoem(title):
		url = r'https://hanyu.baidu.com/s?wd=' + parse.quote(title)
		#要提前安装好Chrome,Chrome会跳出来,听前辈说,有个无头的chrome,不过遗憾的是我没找到    	
		brower = webdriver.Chrome() 
    	brower.get()
    	wait = WebDriverWait(brower, 10)
    	wait.until(expected_conditions.presence_of_element_located((By.ID, 'main')))
    	soup = BeautifulSoup(brower.page_source, 'html.parser')
    	brower.close()

F12直接上网页源码
image.png
可以看到,正文全都在id为body_p的p标签中
所以我们可以

text = soup.findAll(id='body_p')
		Bpoem = ''
		for sentence in text:
			Bpoem += sentence
		return Bpoem

这样就得到了我们的爬虫1.0了,测试一下
image.png

issue

貌似很顺利,但是,古诗文的题目可不像身份证号一样独一无二,当你搜索《晓出》时
image.png
你会发现,html文档根本没有id为body_p的p标签,取而代之的是一个列表,古诗文在class为poem-list-item-body的div中

debug

现在,我们需要用“作者”来筛选数据了。不难发现,作者与古诗文是一一对应的,只要我们获取到作者所在列表的index,就能通过该index定位古诗文了。

code

由于这个古诗爬虫被我运用到了QQBot,所以我在这里做了消息分割处理,你完全可以设置两个参数

def getpoem( msg ):
		arg = msg.split('#')
		title = arg[0]
		author = ''
		if '#' in msg:
			author = arg[1]

接下来是debug部分,在获取到text后对数据进行检验

	if text == []:
		if author == '':
			return '无法获取,试试加上作者吧!PS:题目与作者要用#隔开哦~'
		authors = soup.findAll(name="div", attrs={"class" :"poem-list-item-info"})
		poems = soup.findAll(name='div',attrs={'class':'poem-list-item-body'})
		for index,tauthor in enumerate(authors):
			if author in tauthor.get_text():
				Bpoem = poems[index].get_text()

看看效果
image.png
现在我们就有了爬虫2.0了

又见issue

害!Bug这个东西,比女朋友还粘人
image.png
我们发现,古诗文后面有省略,这是这么回事呢?看看网页,走你(PS:为什么网页暗了呢?因为我写到这的时候已经是凌晨一点多了,眼睛重要,阿巴阿巴阿巴阿巴阿巴)

image.png

我们发现,因为古诗文篇幅太长,所以在列表中简略显示了,所以我们获取到的古诗文数据自然不完整了,这下怎么办呢?

网页源码分析

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-34siX3Gn-1593673362075)(https://i.loli.net/2020/06/29/IPsHytzJ2FnhUQx.png)]
按照用户的操作,ta在选择之后会点击相应的标题链接(即对应的a标签),那么就会跳转到相应的网页,所以,我们要做的就是找到与作者相匹配的a链接的href属性值,然后接下来的操作就像我们的爬虫1.0一样了

debug

首先定义一个获取网页的函数getsoup()

def getsoup(url):
    	brower = webdriver.Chrome()
    	brower.get(url)
    	wait = WebDriverWait(brower, 10)
    	wait.until(EC.presence_of_element_located((By.ID, 'main')))
    	soup = BeautifulSoup(brower.page_source, 'html.parser')
    	brower.close()
    	return soup

然后,把url分成base和参数,base后面要用

base_url = r'https://hanyu.baidu.com'
    url = base_url + '/s?wd=' + parse.quote(title)

    soup = getsoup(url)
    text = soup.findAll(id='body_p')

重头戏来了,从网页源代码可以看出,作者所在的div与a标签是兄弟关系,与poem-list-item的div是父子关系

image.png

遍历poem-list-item,如果author在poem-list-item-info的text中,就去获取它的兄弟标签,即a标签的href,再getsoup,像爬虫1.0一样查找body_p

items = soup.findAll(name='div', attrs={'class': 'poem-list-item'})
        for item in items:
            for child in item.children:
				# 不知为啥会匹配到element.NavigableString的child,这里得先过滤一下
                if type(child) is element.Tag and author in child.get_text():
                    link = item.a['href']
                    text = getsoup(base_url + link).findAll(id='body_p')
                    break
            if text != [] :
            	break

测试一下
image.png
image.png

Github

源代码尽在
Github

  • 0
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

正崽不emo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值