python爬虫使用xpath及bs4解析数据

python使用bs4获取图片

序言

各位大佬,本人为完全零基础的新人一枚,最近在新课培训中学习爬虫,回顾来到这的三个多月时间,一点一滴,一分一秒都不是那么轻松容易,但是我相信我的选择是正确的,本博文完全是为了记笔记自用,有些啰嗦,敬请见谅,同时记录的有什么问题也希望各位大佬高抬贵手给予指出,感谢!!!!!!!

1.获取网页源代码

我们以站长素材网为标准

https://sc.chinaz.com/tupian/

首先进入网站找到网址:在这里插入图片描述
然后再将自己的User-Agent找到:在这里插入图片描述
然后开始获取网页源代码,并写入一个执行主程序:

class Sc_China(object):
	def __init__(self):
		self.url = 'https://sc.chinaz.com/tupian/'#需爬取网页网址
		self.headers = {
			'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36'
		}#用来让网络协议的对端来识别发起请求的用户代理软件的应用类型、操作系统、软件开发商以及版本号。
		self.num = 1
		
	#爬取网页源代码
	def get_source(self):
		requester = requests.get(self.url , headers=self.headers)
		if requester.status_code == 200:#判断是否连接网页成功
			return requester.text#返回网页源码
		else:
			return None#返回空
			
	#主程序		
	def main(self):
		req = self.get_source()
		print(req)

#入口程序(判断是否当前程序为源程序运行)
if __name__ == '__main__':
	res = Sc_China()
	res.main()

然后开始分析网页查看需爬取图片所在链接:在这里插入图片描述
通过查看审查元素发现所有图片的信息都保存在一个**class=“item masonry-brick”**的div标签里。需注意这里的class与源码中的不一定一样需到源码中确认,如图:在这里插入图片描述
需重新找到正确的class属性:在这里插入图片描述

这里可以看出正确的class属性为:class=“item”(红色方框区域),并可以看出上级div标签的class属性为:class=“tupian-list com-img-txt-list”(绿色方框区域);下级有两个标签imgdiv(class=“bot-div”)",通过跳转几个网址会发现,img标签下的两个地址均为缩略图,但div标签下的href属性中的地址为详情页,其中有下载按钮可以获取原图。
那么我们就先获取div标签下的href属性中的地址(这里偷个懒用xpath解析源码了),返回的是一个列表,我们再遍历一下列表,发现返回的是一个不完整的地址(/tupian/23022408830.htm),然后我们回到图片的详情页发现完整地址是:https://sc.chinaz.com/tupian/23022408830.htm,那么我们在获取到的字符串中加一个https://sc.chinaz.com,并再次调用网页源码抓取函数,代码如下:

	def Source_Data_1(self , response):
		html = etree.HTML(response)#解析网页源码
		data_list = html.xpath('//div[@class="tupian-list com-img-txt-list"]//div[@class="item"]')#提取标签源码
		for data in data_list:
			req = data.xpath('./div/a/@href')[0]#获取详情页网址
			self.url = 'https://sc.chinaz.com' + req#补全网址
			b = self.get_source()#获取详情页源码
		
	#同时将main函数修改为:
	def main(self):
		req = self.get_source()
		self.Source_Data_1(req)#调用Source_Data_1函数,并将网页源代码传入

然后,再次开始分析详情页网页,发现下载按钮对应的标签中就有原图地址:
在这里插入图片描述

我们开始直接提取这个地址(这次就使用bs4进行解码了):

	def Source_Data(self, req):
		s = BeautifulSoup(req , 'lxml')#源码解析
		data_list = s.find_all('p' , class_="bg-bull btn-p com-right-down-btn")#获取标签数据
		shuju = data_list[0].find_all("a")[0].get('href')#提取图片地址
		print(shuju)

最后开始进行图图片下载:

	def Sava_Data(self, shuju):
		with open('./img/%d' %self.num + os.path.splitext(shuju)[-1], 'wb') as f:#新建一个二进制文件进行数据存储
			reqs = requests.get(shuju).content#获取原图数据
			f.write(reqs)#写入
			print(f'第{self.num}张图片')
			self.num = self.num + 1

最后就可以欣赏美美的原图了
总结了一下,基础和页面分析是真的很重要,本来想把图片名也爬下来直接就不用命名了,但发现全是乱码,还没找到解决办法,就先从1开始命名了。全部源码如下:

# -*- coding:utf-8 -*-
import os
from lxml import etree

import requests
from bs4 import BeautifulSoup

class Sc_China(object):
	def __init__(self):
		self.url = 'https://sc.chinaz.com/tupian/'
		self.headers = {
			'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36'
		}
		self.num = 1

	def get_source(self):
		requester = requests.get(self.url , headers=self.headers)
		if requester.status_code == 200:
			return requester.text
		else:
			return None

	def Source_Data(self, req):
		s = BeautifulSoup(req , 'lxml')
		data_list = s.find_all('p' , class_="bg-bull btn-p com-right-down-btn")
		shuju = data_list[0].find_all("a")[0].get('href')
		print(shuju)
		self.Sava_Data(shuju)

	def Source_Data_1(self , response):
		html = etree.HTML(response)
		data_list = html.xpath('//div[@class="tupian-list com-img-txt-list"]//div[@class="item"]')
		print(data_list)
		for data in data_list:
			self.url = 'https://sc.chinaz.com/' + data.xpath('./div/a/@href')[0]
			b = self.get_source()
			print(data.xpath('./div/a/@href')[0])
			self.Source_Data(b)

	def Sava_Data(self, shuju):
		with open('./img/%d' %self.num + os.path.splitext(shuju)[-1], 'wb') as f:
			reqs = requests.get(shuju).content
			f.write(reqs)
			print(f'第{self.num}张图片')
			self.num = self.num + 1

	def main(self):
		req = self.get_source()
		self.Source_Data_1(req)

if __name__ == '__main__':
	res = Sc_China()
	res.main()
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值