爬虫爬取GIF发源地__python

博主一个月前接触python,不得不说python身为胶水语言,有着自己得天独厚的优势。博主作为编程小白,在经过一天的奋战后,写出来个凑合能用的python spider 在对代码进行改进捕捉了requestException错误之后,爬虫实测可以一直运行下去,爬到一堆污污的东西。。。
兄弟们你们贴代码给我个评论啊,冷清的一批,谢谢啊各位
爬取结果如下图:
在这里插入图片描述
源代码如下:

import os
import requests
from bs4 import BeautifulSoup
from multiprocessing import Pool
import time
from requests.exceptions import RequestException


def Download_gif(url,path):
	headers={
			'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36',
			'Connection':'close'
			}
	html=requests.get(url,headers=headers)
	soup=BeautifulSoup(html.text,'html.parser')
	gif_url=soup.find_all('a',class_='focus')		#找出单页上的所有链接,返回一个list,这个list由一系列字典组成
	for gif_url in gif_url:				#迭代出每个字典
		gif_url=gif_url['href']		#每个字典的key为href时对应的value为链接
		html=requests.get(gif_url,headers=headers)			#对解析出的链接进行请求
		soup=BeautifulSoup(html.text,'html.parser')			#soup库进行解析
		page=soup.find('div',class_='article-paging').find_all('span')		#进入链接发现是分页形式,所有找出链接上的总页数
		page=page[-1].text							#发现div标签,class为article-paging的标签内的最后一个span标签为页数
		each_url=gif_url						#这里一定要将url区分开来,一个用each_url,一个用gif_url,否则会发生未知错误,调试过程会发现
		for i in range(1,int(page)+1):			#构造列表生成式,对应每一页链接进行图片或gif下载
			pic=each_url+str(i)				#每一页链接
			html=requests.get(pic,headers=headers)		#请求每一页链接
			soup=BeautifulSoup(html.text,'html.parser')		#解析每一页链接
			pic_url=soup.find_all('img',class_='aligncenter')		#发现每一页链接上的img标签,class_为aligncenter的为图片或gif_url
			for a_url in pic_url:			#迭代出每个图片或Gif链接(为字典形式)
				os.chdir(path)				#将目录切换至自己电脑上的path目录
				a_url=a_url['src']			#gif链接中的src对应图片链接
				if a_url==None:					#加入判断,如果图片无链接,pass,让爬虫能够运行下去
					pass
				try:
					html=requests.get(a_url,headers=headers)		#请求图片链接,得到图片或Gif的文件流
					requests.adapters.DEFAULT_RETRIES = 5		#加入重复请求次数
					file_name=a_url.split('/')[-1]		#给出文件名
					f=open(file_name,'wb')		#写入文件
					f.write(html.content)
					time.sleep(0.000001)
					f.close()
					time.sleep(0.2)			
				except RequestException:
					return None
				
if __name__=='__main__':
	path='C://Users/panenmin/Desktop/GIF/'		#定义path,这里可以更改为自己电脑上的路径,一定用正斜线
	start_url='https://www.gifjia5.com/category/neihan/page/'	#定义start_url
	pool=Pool(6)			#构建进程池
	for i in range(1,23):		#构造列表生成式
		url=start_url+str(i)		#构造每一页链接
		pool.apply_async(Download_gif,args=(url,path))	#传入函数和函数的参数
	pool.close()		
	pool.join()



代码的逻辑确实有点混乱,主要思路是定义一个爬取单页的函数。该函数有三层迭代嵌套。第一层迭代出所有的单页上的链接,找出每个链接上的页数之后,构造列表生成式,对每一页进行循环,筛选出真正的图片Gif链接,对于每一个gif or jpg链接,requests请求得到图片或gif文件流,并写入文件。
对于Main函数,思路为对于首页的分页进行循环执行定义的Download_gif函数,即对每页上的链接进行函数流程的执行。同时加入了多进程Pool。
在函数内部,用到了time模块,time.sleep()是让spider向服务器请求的不那么频繁,防止封ip等等骚操作。
虽然这个spider比较rubbish,但是也是我code半天写出来的,还希望刚入门爬虫的朋友们能够从里边学到一点东西,同时明天我将贴上具体的开发过程。(楼主苦逼上班族,但是比较闲。)
附上我最喜欢的一句话,talk is cheap,show me the code
开发过程:
1:首先进入gif发源地首页,查看页面布局
GIF发源地内涵首页

用chrome浏览器开发者选项,发现如下:
开发者选项界面
可以发现a标签,class属性为focus的节点里面包含有首页所有的链接
href对应的即为首页上所有的链接

我们首页上第一个链接,如下图:
首页上第一个链接得到界面

往下翻,发现这个界面仍有分页
每个套图链接分页情况

打开开发者选项,找出最大页数以及jpg or gif链接

img标签,class为aligncenter的部分包含了图片链接

找出最大页数:

div标签,class为article-paging的部分为页数部分

找出链接后,对每页进行循环请求图片or gif 链接,得到文件流,写入文件。

以上函数部分的爬取思路,即爬单页思路,对于爬取多页,思路很简单了,总共23页,循环爬取

if name==‘main’:
path=‘C://Users/panenmin/Desktop/GIF/’ #定义path,这里可以更改为自己电脑上的路径,一定用正斜线
start_url=‘https://www.gifjia5.com/category/neihan/page/’ #定义start_url
pool=Pool(6) #构建进程池
for i in range(1,23): #构造列表生成式
url=start_url+str(i) #构造每一页链接
pool.apply_async(Download_gif,args=(url,path)) #传入函数和函数的参数
pool.close()
pool.join()

并且将爬取单页的函数参数传进去,大功告成。但是博主发现,该爬虫需要改进的地方仍有很多,比如爬取一段时间,会发现远程主机强制让爬虫掉线(短暂性封Ip),考虑加入代理池 。开发过程中遇到许多问题,也算是边学边用,知行合一。希望刚入门爬虫的朋友们争取自己写出点东西出来,这样理解才更深刻。

更新一下代码,博主在爬取的时候出现了关于file_name的os错误,故更新源代码。对file_name进行判断`

import os
import requests
from bs4 import BeautifulSoup
from multiprocessing import Pool
import time
from requests.exceptions import RequestException


def Download_gif(url,path):
	headers={
			'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36',
			'Connection':'close'
			}
	html=requests.get(url,headers=headers)
	soup=BeautifulSoup(html.text,'html.parser')
	gif_url=soup.find_all('a',class_='focus')		#找出单页上的所有链接,返回一个list,这个list由一系列字典组成
	for gif_url in gif_url:				#迭代出每个字典
		gif_url=gif_url['href']		#每个字典的key为href时对应的value为链接
		html=requests.get(gif_url,headers=headers)			#对解析出的链接进行请求
		soup=BeautifulSoup(html.text,'html.parser')			#soup库进行解析
		page=soup.find('div',class_='article-paging').find_all('span')		#进入链接发现是分页形式,所有找出链接上的总页数
		page=page[-1].text							#发现div标签,class为article-paging的标签内的最后一个span标签为页数
		each_url=gif_url						#这里一定要将url区分开来,一个用each_url,一个用gif_url,否则会发生未知错误,调试过程会发现
		for i in range(1,int(page)+1):			#构造列表生成式,对应每一页链接进行图片或gif下载
			pic=each_url+str(i)				#每一页链接
			html=requests.get(pic,headers=headers)		#请求每一页链接
			soup=BeautifulSoup(html.text,'html.parser')		#解析每一页链接
			pic_url=soup.find_all('img',class_='aligncenter')		#发现每一页链接上的img标签,class_为aligncenter的为图片或gif_url
			for a_url in pic_url:			#迭代出每个图片或Gif链接(为字典形式)
				os.chdir(path)				#将目录切换至自己电脑上的path目录
				a_url=a_url['src']				#gif链接中的src对应图片链接
				file_name=a_url.split(r'/')[-1]
				if file_name[-4:]!='.gif' and file_name[-4:]!='.jpg' and file_name[-4:]!='jpeg':
					return None
				if a_url==None:					#加入判断,如果图片无链接,pass,让爬虫能够运行下去
					pass
				try:
					html=requests.get(a_url,headers=headers)		#请求图片链接,得到图片或Gif的文件流
					requests.adapters.DEFAULT_RETRIES = 5		#加入重复请求次数
					f=open(file_name,'wb')		
					f.write(html.content)
					time.sleep(0.000001)
					f.close()
					time.sleep(0.2)			
				except RequestException:
					return None
				
if __name__=='__main__':
	path='D://GIF/'		#定义path,这里可以更改为自己电脑上的路径,一定用正斜线
	start_url='https://www.gifjia5.com/category/neihan/page/'	#定义start_url
	pool=Pool(6)			#构建进程池
	for i in range(1,23):		#构造列表生成式
		url=start_url+str(i)		#构造每一页链接
		pool.apply(Download_gif,args=(url,path))			#传入函数和函数的参数
		print('第i页已爬完')
	pool.close()		
	pool.join()

这里说明一下,写代码时一定要加注释,这样不只是便于别人阅读,在将来对代码出现bug时,自己可以对代码有一个清晰的思路,可以便于维护。当然,大神除外。。。

发布了19 篇原创文章 · 获赞 1 · 访问量 3139

猜你喜欢

转载自blog.csdn.net/qq_41603639/article/details/84933660
今日推荐