Python爬虫过程 爬取www.yikexun.cn/励志句子过程(双请求)

本文介绍了一种使用Python爬虫技术批量抓取网站上的励志文章的方法,包括如何解析URL、发送请求、使用正则表达式提取标题和文章内容,并将其保存为HTML文件的全过程。

学了大概4、5天的爬虫终于能爬点图片和文章了
其实这两个差不多,后面一个稍微复杂一点
这次来讲解一下怎么爬取标题的这个网址
在这里插入图片描述
要做的是爬取这些文章,我们输入起始页码和结束页码,爬取页码之间的每篇文章
我们现在看到的是标题,标题点进去之后才是我们要的文章,我们要把每篇文章写进一个html文件里
需求就是这样,开工!
首先我们看看url和页码有什么关系
在这里插入图片描述
在这里插入图片描述
很明显就是后面的50_n.html就是决定页码的地方了
那么第一步先去获取响应

import urllib.request
import urllib.parse
import re
import os
import time

def main():
	url = 'http://www.yikexun.cn/lizhi/qianming/'
	start_page = int(input('输入起始页码:'))
	end_page = int(input('输入结束页码:'))

	for page in range(start_page, end_page + 1):
		#生成请求对象
		request = handle_request(url, page)
		#发送请求,获取响应
		content = urllib.request.urlopen(request).read().decode()
		#下载句子,封装成函数
		download(content)

因为不止有一页,我用了一个循环,每一页发送一个请求
然后把生成请求对象封装成一个函数,可以让代码更简洁

def handle_request(url, page=None):
	#如果没有页数这个参数,就不拼接url
	if page != None:
		url = url + 'list_50_' + str(page) + '.html'
	# print(url)
	headers = {
		'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3590.0 Safari/537.36',
	}
	request = urllib.request.Request(url=url, headers=headers)
	return request

函数根据页数和url拼接,得到我们想要的那一页的网址
打印出来大概是这样

http://www.yikexun.cn/lizhi/qianming/list_50_1.html
http://www.yikexun.cn/lizhi/qianming/list_50_2.html
http://www.yikexun.cn/lizhi/qianming/list_50_3.html

那个if条件句是为了另一个请求做准备,因为另一个请求并不需要page这个参数,提高代码的重用
然后就是仿造信息头,生成请求对象,再返回到主函数

回到主函数,有了请求自然要去获取响应
我们把获取的响应直接转成字符串(用decode()函数)
这样方便我们后边用正则处理

处理句子我们也封装成一个函数

def download(content):
	#加了re.S才能用 .*? 匹配换行符,想获取哪个,哪个加小括号
	pattern = re.compile(r'<h3><a href="(/lizhi/qianming/\d+\.html)"><b>(.*?)</b></a>', re.S)
	#把爬到的内容放到 lt 里面,以列表的格式。
	lt = pattern.findall(content)
	# print(lt)
	#遍历列表
	for href_title in lt:
		#拼接这个文章的 url,文章的url是列表每个元组中的第零个元素
		a_herf = 'http://www.yikexun.cn' + href_title[0]
		#获取文章标题
		title = href_title[-1]
		#发送请求,再封装成一个函数,直接获取封装好的内容
		text = get_text(a_herf)
		#写入到html文件
		string = '<h1>%s</h1>%s' %(title, text)
		with open('lizhi.html', 'a') as fp:
			fp.write(string)

第一步就是去匹配要的内容,这之前我们要看看网页的元素内容,鼠标放在文章标题上右键,检查就能看到网页的代码
在这里插入图片描述
我匹配的仅仅是<h3>标签里的内容每一篇文章都是
很明显,我们也需要<a>标签中的url,因为那个就是我们文章的url,后面二次请求就要用到

pattern = re.compile(r'<h3><a href="(/lizhi/qianming/\d+\.html)"><b>(.*?)</b></a>', re.S)

解释下这个正则,用到了 \d+(.*?)

第一个是用来匹配数字,因为发现网页代码中,每篇文章的那里都不一样

第二个是用来匹配<b>标签中的文字,也就是标题

要注意的是 (.*?) 是非贪婪模式,后面要加上re.S这个参数才能匹配换行符,因为本来 “.” 就是匹配换行符以外的字符。至于为什么这么用,后面估计会有很多用 “.*?” 来匹配,所以现在就这么用着先

还有 \d+\. 后面的 \. 是转义字符,把". "当作字符而不是正则表达式

然后我们用 findall() 方法把之前获取的响应内容当作参数放里面,返回一个列表。列表中每一个元素都是一个元组,元组中的第一个是每一篇文章的标识,第二个是文章的标题,可以看到我们正则表达式也就用了两个,所以匹配出两个元素

[('/lizhi/qianming/20190841364.html', '愿有前程可奔赴,亦有岁月可回首——前程似锦要靠自己打拼'), ('/lizhi/qianming/20190741356.html', '人活着,不是为了被打败——为自己争口气'), ('/lizhi/qianming/20190741353.html', '哭着吃过饭的人,是能够走下去的——时刻把握自己的梦想'), ('/lizhi/qianming/20190741350.html', '活着就意味着必须做点什么,请好好努力——生活很难但请你坚持'), ('/lizhi/qianming/20190741338.html', '你想要赢,拿命来换——奋斗者的必读语录'), ('/lizhi/qianming/20190741330.html', '没有一个冬天不可逾越,没有一个春天不会来临——年轻人的励志经典语录'), ('/lizhi/qianming/20190741326.html', '钱非万能 无钱万万不能——现实的残酷要求你去拼搏'), ('/lizhi/qianming/20190641322.html', '前面的路还很远,你可能会哭,但是一定要走下去——励志追梦人的经典语录'), ('/lizhi/qianming/20190541318.html', '越努力越幸运,这句话真实存在——离梦想更近一步'), ('/lizhi/qianming/20190541315.html', '不要低头,要往上看,要去更高的地方——经典励志语录'), ('/lizhi/qianming/20190541314.html', '人一旦无畏,人生就会无限——成为你想成为的那个人'), ('/lizhi/qianming/20190541310.html', '虽然很辛苦,但努力过真好——将来的你会感谢现在的自己'), ('/lizhi/qianming/20190541303.html', '祝我们永远年轻永远热泪盈眶——年轻人努力奋斗的经典励志语录'), ('/lizhi/qianming/20190541301.html', '如果我踩不过荆棘,那么便不配得到风光——2019励志人生青春语录'), ('/lizhi/qianming/20190541295.html', '我知道你很累,但别人都在飞。——2019高考加油励志经典语录')]

这是我匹配出来结果,只能单行显示。。。每个小括号就是一个元组

到这里,文章标题我们已经处理好了,文章的url也获取了,所以现在发送第二次请求,获取文章内容

打开第一篇
在这里插入图片描述
开发者还是挺贴心的,直接告诉我们这内容,打开方法还是一样,右键检查

要匹配的就是 <div class=neirong> 这个标签的东西

def get_text(href):
	#调用函数handle_request,生成请求对象
	request = handle_request(href)
	#发送请求,获取响应内容
	content = urllib.request.urlopen(request).read().decode()
	#处理获取到的每一篇文章
	pattern = re.compile(r'<div class="neirong">(.*?)</div>', re.S)
	#返回列表
	lt = pattern.findall(content)
	# print(lt)
	# exit()
	#返回的列表只有一个元素
	return lt[0]

直接看正则,没什么好说的,(.*?)匹配这标签之间的任何字符,这么理解就可以了
虽然网上看正则表达式规则蛮多的,实际用起来确实只有几个

直接返回列表,这里面就是文章了,因为只有一个元素,return lt[0] 就可以返回字符串,里面还是包含标签的,写进html文件时就能直接显示了

#写入到html文件
		string = '<h1>%s</h1>%s' %(title, text)
		with open('lizhi.html', 'a') as fp:
			fp.write(string)

最后一步,在 download(content) 里面,然后就完成啦
看成果
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


更新一波,去除掉图片的标签,直接上代码吧

def get_text(href):
	#调用函数handle_request,生成请求对象
	request = handle_request(href)
	#发送请求,获取响应内容
	content = urllib.request.urlopen(request).read().decode()
	#处理获取到的每一篇文章
	pattern = re.compile(r'<div class="neirong">(.*?)</div>', re.S)
	#返回列表
	lt = pattern.findall(content)
	text = lt[0]
	#把里面的图片清除
	patt = re.compile(r'<img .*?>', re.M)
	text = patt.sub('', text)
	# print(text)
	# exit()
	#返回的列表只有一个元素
	return text
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值