爬虫网站程序-Python爬虫(十九)爬取峰会网站——网络上常见的gif动画

上面写的是什么~

好久没写爬虫相关的文章了。 明天我会花时间与大家分享我之前制作的一个程序。

经常访问A站和B站的人一定熟悉一个叫做“网络常见GIF”的程序

明天我会分享如何通过爬虫手动将这些动作收集到我的笔记本中(虽然这个程序是五月份写的,但直到现在我仍然不想分享)。

1.思路分析

根据爬虫的基本规则:

1.找到目标

2. 抓住目标

3. 处理目标内容并获取有用信息

1.首先我们的目标是:找动画图片,去GIFFCC.COM

这个网站是一个峰会式的网站爬虫网站程序,分为几个类别。 简而言之,尝试各种动画。

我们的目标是找到收集这些活动的计算机。

2. 查看每个模块的 URL,了解规则是什么。

'#39;,#其他各种GIF动画来源

'#39;,#美美GIF动态图源

'#39;,#悬疑魔幻电影GIF动态图源

'#39;,#喜剧恶搞视频GIF动态图源

'#39;,#动作冒险电影GIF动态图源

'#39;#惊悚悬疑系列GIF动态图源

是的,没错,如果您以访问者的身份访问它,每只蓝筹股的 URL 将如下所示 - 1.html

那么每个模块的内容有什么规则呢? 我们直接上图:

我们关注的是当前页面的URL和页脚编号。 跳转到第二页后,地址变为:

换句话说,URL的规则是

这里需要注意的一件事是网站上的图片是动态加载的。 只要向下滑动,下面的图片就会逐渐突出显示。 我们暂时把这个写下来。

3、每个动画图片所在页面的规则

虽然这没有什么规则,但只要我们找到单个图像的地址,就没什么难处理的了。

二、复工

1.获取入口页面内容

即根据传入的URL,获取整个页面的源代码

	#仅仅获取页面内容
	def get_html_Pages(self,url):  
		try:   
			#browser = webdriver.PhantomJS(executable_path=r'C:Python27Scriptsphantomjs.exe') 
			browser = webdriver.PhantomJS() 
			browser.get(url)
			html = browser.execute_script("return document.documentElement.outerHTML")
			browser.close()
			html=HTMLParser.HTMLParser().unescape(html).decode('utf-8')
			return html
        #捕捉异常,防止程序直接死掉    
		except Exception,e:  
			print u"连接失败,错误原因",e
			return None   

这里我们使用了webdriver和PhantomJS模块爬虫网站程序,为什么呢? 由于网页是动态加载的,因此可以捕获更多数据。

那么这里还有一个疑问,为什么没有滑动什么的,得到的数据

2.获取页脚数量

	#获取页码		
	def get_page_num(self,html):
		doc = pq(html)  
		print u'开始获取总页码'
		#print doc('head')('title').text()#获取当前title
		try:
			#如果当前页面太多,超过8页以上,就使用另一种方式获取页码
			if doc('div[class="pg"]')('[class="last"]'):
				num_content= doc('div[class="pg"]')('[class="last"]').attr('href')
				print  num_content.split('-')[1].split('.')[0]
				return num_content.split('-')[1].split('.')[0]
			else:
				num_content= doc('div[class="pg"]')('span')
				return filter(str.isdigit,str(num_content.text()))[0]
		#如果获取页码失败,那么就返回1, 即值获取1页内容	
		except Exception,e:
			print u'获取页码失败'.e
			return '1'

这里的页脚处理使用了一个模块pq,即PyQuery

frompyqueryimportPyQueryaspq

我们使用 PyQuery 来查找我们需要的元素。 我觉得这样比较容易处理,也比较方便。

同时,这里的处理也有点意思。 如果您查看此页面,您会发现每个模块的前面和底部都有一个页脚编号。 我将在这里裁剪它,因为我们只需要一个页脚编号,即 Can

3-6 让我们完成第三步到第六步。

或许就是根据页脚的数量来遍历,获取每个页面的内容。

然后获取每个页面的所有图片地址

			print  u'总共有 %d页内容' % int(page_num)
			#3.遍历每一页的内容
			for num in range(1,int(page_num)):
				#4.组装新的url
				new_url = self.url.replace( self.url.split('-')[2],(str(num)+'.html') )
				print u'即将获取的页面是:',new_url
				#5.加载每一页内容,获取gif list 的内容
				items=self.parse_items_by_html(self.get_all_page(new_url))
				print u'在第%d页,找到了%d 个图片内容' % (num,len(items))
				#6.处理每一个元素的内容
				self.get_items_url(items,num)

获取每个页面的内容时,需要重新组装页面地址。

#4.组装新的url
				new_url = self.url.replace( self.url.split('-')[2],(str(num)+'.html') )
				print u'即将获取的页面是:',new_url

有了新的地址,就可以获取当前页面的内容,进行数据处理,获取每张图片的地址列表。

#5.加载每一页内容,获取gif list 的内容
				items=self.parse_items_by_html(self.get_all_page(new_url))
				print u'在第%d页,找到了%d 个图片内容' % (num,len(items))

	#解析页面内容,获取gif的图片list
	def parse_items_by_html(self, html):  
		doc = pq(html)  
		print u'开始查找内容msg'     
		return doc('div[class="c cl"]')

获取图片列表后,再次解析,获取每张图片的URL。

#解析gif 的list ,处理每一个gif内容
	def get_items_url(self,items,num):
		i=1
		for article in items.items():
			print u'开始处理数据(%d/%d)' % (i, len(items))
			#print article
			self.get_single_item(article,i,num)
			i +=1
	
	#处理单个gif内容,获取其地址,gif 最终地址
	def get_single_item(self,article,num,page_num):
		gif_dict={}
		#每个页面的地址
		gif_url= 'http://gifcc.com/'+article('a').attr('href')
		#每个页面的标题
		gif_title= article('a').attr('title')
		
		#每张图的具体地址
		#html=self.get_html_Pages(gif_url)
		#gif_final_url=self.get_final_gif_url(html)
	 
		gif_dict['num']=num
		gif_dict['page_num']=page_num
		gif_dict['gif_url']=gif_url
		gif_dict['gif_title']=gif_title
		self.gif_list.append(gif_dict)
		data=u'第'+str(page_num)+'页|t'+str(num)+'|t'+gif_title+'|t'+gif_url+'n'
		self.file_flag.write(data)

这里,整合数据,准备将数据写入数据库

7.将图片保存到本地并将数据写入数据库

#使用urllib2来获取图片最终地址
	def get_final_gif_url_use_urllib2(self,url):
		try:
			html= urllib2.urlopen(url).read()
			gif_pattern=re.compile('<div align="center.*?',re.S)
			return re.search(gif_pattern,html).group(1)
		except Exception,e:
			print u'获取页面内容出错:',e
	#最终处理	存贮数据
	def get_gif_url_and_save_gif(self):
		def save_gif(url,name):
			try:
				urllib.urlretrieve(url, name)
			except Exception,e:
				print '存贮失败,原因:',e
		for i in range(0,len(self.gif_list)):
			gif_dict=self.gif_list[i]
			gif_url=gif_dict['gif_url']
			gif_title=gif_dict['gif_title']
			
			#依然使用webdriver获取最终的gif地址
			final_html=self.get_html_Pages(gif_url)
			gif_final_url=self.get_final_gif_url(final_html)
			#使用另外一种方式(urllib2)获取最终地址
			#gif_final_url=self.get_final_gif_url_use_urllib2(gif_url)
			
			gif_dict['gif_final_url']=gif_final_url
			print u'开始向数据库写入第%d页第%d项数据,并开始存贮图片到本地 ' % (gif_dict['page_num'],gif_dict['num'])
			self.BookTable.insert_one(gif_dict)
			gif_name=self.dir_name+'/'+gif_title+'.gif'
			save_gif(gif_final_url,gif_name)

虽然到这里大致的内容已经完成了。

我们能否将本次峰会各模块的动画保存在本地,同时将数据加载到数据库中?

三数据库筛选

把数据加载到数据库后,我以为调用数据库就可以直接保存图片了

(为什么我有这个意见?因为我发现如果我直接在主程序中存储图片,运行速度太慢,最好把数据全部放到数据库中,然后专门调用数据库来存储图片)

然而,这里却发现了一个问题。 数据里的内容非常多。 后来我们发现很多内容是重复的,所以我们需要对数据库进行去重。

虽然我在之前的文章中已经写过重复数据删除的内容(当我写那篇文章的时候,爬虫已经完成了~)

主要思想是对某个元素的个数进行操作。 pymongo 上有一种方法可以计算指定元素的数量。 如果当前只有一个元素,则忽略它。 如果不是元素,则将其删除。

核心代码如下:

for url in collection.distinct('name'):#使用distinct方法,获取每一个独特的元素列表
		num= collection.count({"name":url})#统计每一个元素的数量
		print num
		for i in range(1,num):#根据每一个元素的数量进行删除操作,当前元素只有一个就不再删除
			print 'delete %s %d times '% (url,i)
			#注意后面的参数, 很奇怪,在mongo命令行下,它为1时,是删除一个元素,这里却是为0时删除一个
			collection.remove({"name":url},0)
		for i in  collection.find({"name":url}):#打印当前所有元素
			print i
	print collection.distinct('name')#再次打印一遍所要去重的元素

4.读取数据库中的内容并存储图片

数据去重后,再次保存图片就方便多了。

那么如果把图片删除了,就不用再运行了,或者有时本地图片占空间,所以只需将数据保存到数据库中即可。

核心代码如下:

def save_gif(url,name):
	try:
		urllib.urlretrieve(url, name)
	except Exception,e:
		print u'存贮失败,原因:',e
client = pymongo.MongoClient('localhost', 27017) 
print client.database_names()
db = client.GifDB
for table in  db.collection_names():
	print 'table name is ',table
	collection=db[table]
	for item in  collection.find():
		try: 
			if item['gif_final_url']:
				url,url_title= item['gif_final_url'],item['gif_title']
				gif_filename=table+'/'+url_title+'.gif'
				print 'start save %s, %s' % (url,gif_filename)
				save_gif(url,gif_filename)
		except Exception,e:
			print u'错误原因:',e

完整代码

01_get_gif_url.py

#coding: utf-8 
from pyquery import PyQuery as pq  
from selenium import webdriver 
import HTMLParser,urllib2,urllib,re,os
import pymongo
import time
import sys  
reload(sys)  
sys.setdefaultencoding('utf-8')  
class download_gif:
	def __init__(self):
		self.url='http://gifcc.com/forum-38-1.html'
		self.url_list=['http://gifcc.com/forum-37-1.html',#其他各种GIF动态图出处 
		'http://gifcc.com/forum-38-1.html', #美女GIF动态图出处 
		'http://gifcc.com/forum-47-1.html',#科幻奇幻电影GIF动态图出处
		'http://gifcc.com/forum-48-1.html',#喜剧搞笑电影GIF动态图出处
		'http://gifcc.com/forum-49-1.html',#动作冒险电影GIF动态图出处
		'http://gifcc.com/forum-50-1.html'#恐怖惊悚电影GIF动态图出处
		]
		self.choices={'1':u'其他各种GIF动态图出处',
		'2':u'美女GIF动态图出处',
		'3':u'科幻奇幻电影GIF动态图出处',
		'4':u'喜剧搞笑电影GIF动态图出处',
		'5':u'动作冒险电影GIF动态图出处',
		'6':u'恐怖惊悚电影GIF动态图出处'
		}
		
		self.dir_name=u'gif出处'
		self.gif_list=[]
		
		self.connection = pymongo.MongoClient()  
		
		#BookTable.insert_one(dict_data)#插入单条数据  
		#BookTable.insert(dict_data)#插入 字典list 数据 
		
	#获取页面内容,并且加载JS, 通过滚动获取页面更多的元素
	def get_all_page(self,url):
		try:
			#browser = webdriver.PhantomJS(executable_path=r'C:Python27Scriptsphantomjs.exe') 
			browser = webdriver.PhantomJS() 
			browser.get(url)
			#time.sleep(3) 
			#页面滚动
			js = "var q=document.body.scrollTop=100000"    
			#for i in range(5):  #调试语句,先暂时不加载太多次数
			for i in range(30):  
				#循环执行下滑页面50次  
				browser.execute_script(js)  
				#加载一次,休息一下  
				time.sleep(1)
				print u'这是第 %d 次划动页面' % i
			# 执行js得到整个页面内容
			html = browser.execute_script("return document.documentElement.outerHTML")
			browser.close()
			html=HTMLParser.HTMLParser().unescape(html)
			return html
		except Exception,e:
			print u'发生错误:',e
	
	#解析页面内容,获取gif的图片list
	def parse_items_by_html(self, html):  
		doc = pq(html)  
		print u'开始查找内容msg'     
		return doc('div[class="c cl"]')
		
	#解析gif 的list ,处理每一个gif内容
	def get_items_url(self,items,num):
		i=1
		for article in items.items():
			print u'开始处理数据(%d/%d)' % (i, len(items))
			#print article
			self.get_single_item(article,i,num)
			i +=1
	
	#处理单个gif内容,获取其地址,gif 最终地址
	def get_single_item(self,article,num,page_num):
		gif_dict={}
		#每个页面的地址
		gif_url= 'http://gifcc.com/'+article('a').attr('href')
		#每个页面的标题
		gif_title= article('a').attr('title')
		
		#每张图的具体地址
		#html=self.get_html_Pages(gif_url)
		#gif_final_url=self.get_final_gif_url(html)
	 
		gif_dict['num']=num
		gif_dict['page_num']=page_num
		gif_dict['gif_url']=gif_url
		gif_dict['gif_title']=gif_title
		self.gif_list.append(gif_dict)
		data=u'第'+str(page_num)+'页|t'+str(num)+'|t'+gif_title+'|t'+gif_url+'n'
		self.file_flag.write(data)
	
	#通过webdriver获得页面内容后,获得最终地址
	def get_final_gif_url(self,html):
		doc = pq(html) 
		image_content= doc('td[class="t_f"]')
		gif_url= image_content('img').attr('src')
		return gif_url
	
	#使用urllib2来获取图片最终地址
	def get_final_gif_url_use_urllib2(self,url):
		try:
			html= urllib2.urlopen(url).read()
			gif_pattern=re.compile('<div align="center.*?',re.S)
			return re.search(gif_pattern,html).group(1)
		except Exception,e:
			print u'获取页面内容出错:',e
	#最终处理	存贮数据
	def get_gif_url_and_save_gif(self):
		def save_gif(url,name):
			try:
				urllib.urlretrieve(url, name)
			except Exception,e:
				print '存贮失败,原因:',e
		for i in range(0,len(self.gif_list)):
			gif_dict=self.gif_list[i]
			gif_url=gif_dict['gif_url']
			gif_title=gif_dict['gif_title']
			
			#依然使用webdriver获取最终的gif地址
			final_html=self.get_html_Pages(gif_url)
			gif_final_url=self.get_final_gif_url(final_html)
			#使用另外一种方式(urllib2)获取最终地址
			#gif_final_url=self.get_final_gif_url_use_urllib2(gif_url)
			
			gif_dict['gif_final_url']=gif_final_url
			print u'开始向数据库写入第%d页第%d项数据,并开始存贮图片到本地 ' % (gif_dict['page_num'],gif_dict['num'])
			self.BookTable.insert_one(gif_dict)
			gif_name=self.dir_name+'/'+gif_title+'.gif'
			save_gif(gif_final_url,gif_name)
		
	#仅仅获取页面内容
	def get_html_Pages(self,url):  
		try:   
			#browser = webdriver.PhantomJS(executable_path=r'C:Python27Scriptsphantomjs.exe') 
			browser = webdriver.PhantomJS() 
			browser.get(url)
			html = browser.execute_script("return document.documentElement.outerHTML")
			browser.close()
			html=HTMLParser.HTMLParser().unescape(html).decode('utf-8')
			return html
        #捕捉异常,防止程序直接死掉    
		except Exception,e:  
			print u"连接失败,错误原因",e
			return None   
	
	#获取页码		
	def get_page_num(self,html):
		doc = pq(html)  
		print u'开始获取总页码'
		#print doc('head')('title').text()#获取当前title
		try:
			#如果当前页面太多,超过8页以上,就使用另一种方式获取页码
			if doc('div[class="pg"]')('[class="last"]'):
				num_content= doc('div[class="pg"]')('[class="last"]').attr('href')
				print  num_content.split('-')[1].split('.')[0]
				return num_content.split('-')[1].split('.')[0]
			else:
				num_content= doc('div[class="pg"]')('span')
				return filter(str.isdigit,str(num_content.text()))[0]
		#如果获取页码失败,那么就返回1, 即值获取1页内容	
		except Exception,e:
			print u'获取页码失败'.e
			return '1'
			
		# filter(str.isdigit,num_content)#从字符串中提取数字
		
	#创建文件夹	
	def mk_dir(self,path):
		if not os.path.exists(path):  
			os.makedirs(path) 
			
	def set_db(self,tablename):
		self.BookDB = self.connection.GifDB         #数据库db的名字  
		self.BookTable =self.BookDB[tablename]           #数据库table表的名字  
			
	#主函数		
	def run(self):
		choice_type=5
		if choice_type:
		#for choice_type in range(len(self.choices)): 
			if  choice_type+1:
				
				self.dir_name=self.choices[str(choice_type+1)].strip()
				self.url=self.url_list[int(choice_type)]
				
				
				print self.dir_name,self.url
		
		
			#0.创建文件夹存贮图片,建立文件存贮内容
			self.mk_dir(self.dir_name)
			self.filename=self.dir_name+'/'+self.dir_name+'.txt'
			print self.filename
			self.file_flag=open(self.filename,'w')
			
			self.set_db(self.dir_name)
			self.BookTable .insert({'filename':self.dir_name})
			
			print self.url
			#1.获取入口页面内容
			html=self.get_html_Pages(self.url)
			
			#2.获取页码数目
			page_num=self.get_page_num(html)
			
			print  u'总共有 %d页内容' % int(page_num)
			#3.遍历每一页的内容
			
			#page_num=3#调试语句,先暂时将页面内容设置的小一点
			for num in range(1,int(page_num)):
				#4.组装新的url
				new_url = self.url.replace( self.url.split('-')[2],(str(num)+'.html') )
				print u'即将获取的页面是:',new_url
				#5.加载每一页内容,获取gif list 的内容
				items=self.parse_items_by_html(self.get_all_page(new_url))
				print u'在第%d页,找到了%d 个图片内容' % (num,len(items))
				#6.处理每一个元素的内容
				self.get_items_url(items,num)
			
			#5.数据全部抓取完毕,开始处理数据
			self.get_gif_url_and_save_gif()
			print 'success'
			
			self.file_flag.close()
		
			
if __name__ == '__main__':  
	print u'''
            **************************************************  
            **    Welcome to Spider of  GIF 出处图片        **  
            **         Created on 2017-05-21                **  
            **         @author: Jimy _Fengqi                **  
            ************************************************** 
	'''  		
	print u''' 选择你要下载的gif图片类型
		1:'其他各种GIF动态图出处'
		2:'美女GIF动态图出处'
		3:'科幻奇幻电影GIF动态图出处'
		4:'喜剧搞笑电影GIF动态图出处'
		5:'动作冒险电影GIF动态图出处'
		6:'恐怖惊悚电影GIF动态图出处'
		'''
	#选择要下载的类型	
	mydownload=download_gif()
	html=mydownload.run()

02_delete_repeat_url_in_mongodb.py

#coding: utf-8 
from pyquery import PyQuery as pq  
from selenium import webdriver 
import HTMLParser,urllib2,urllib,re,os
import pymongo
import time
import sys  
reload(sys)  
sys.setdefaultencoding('utf-8')  
import pymongo  
def save_gif(url,name):
	try:
		urllib.urlretrieve(url, name)
	except Exception,e:
		print '存贮失败,原因:',e
		
def print_database_and_table_name():	
	import pymongo
	client = pymongo.MongoClient('localhost', 27017) 
	print client.database_names()
	for database in client.database_names():
		for table in  client[database].collection_names():
			print 'table  [%s]  is in database [%s]' % (table,database)
def delete_single_database_repeat_data():
	import pymongo
	client = pymongo.MongoClient('localhost', 27017) 
	db=client.GifDBtemptemp2#这里是将要清洗数据的数据库名字
	for table in  db.collection_names():
		print 'table name is ',table
		collection=db[table]
		for url in collection.distinct('gif_title'):#使用distinct方法,获取每一个独特的元素列表
			num= collection.count({"gif_title":url})#统计每一个元素的数量
			print num
			for i in range(1,num):#根据每一个元素的数量进行删除操作,当前元素只有一个就不再删除
				print 'delete %s %d times '% (url,i)
				#注意后面的参数, 很奇怪,在mongo命令行下,它为1时,是删除一个元素,这里却是为0时删除一个
				collection.remove({"gif_title":url},0)
			for i in  collection.find({"gif_title":url}):#打印当前所有元素
				print i
def delete_repeat_data():
	import pymongo
	client = pymongo.MongoClient('localhost', 27017) 
	db = client.local
	collection = db.person
	
	for url in collection.distinct('name'):#使用distinct方法,获取每一个独特的元素列表
		num= collection.count({"name":url})#统计每一个元素的数量
		print num
		for i in range(1,num):#根据每一个元素的数量进行删除操作,当前元素只有一个就不再删除
			print 'delete %s %d times '% (url,i)
			#注意后面的参数, 很奇怪,在mongo命令行下,它为1时,是删除一个元素,这里却是为0时删除一个
			collection.remove({"name":url},0)
		for i in  collection.find({"name":url}):#打印当前所有元素
			print i
	print collection.distinct('name')#再次打印一遍所要去重的元素
delete_single_database_repeat_data()

03_from_mongodb_save_pic.py

#coding: utf-8 
from pyquery import PyQuery as pq  
from selenium import webdriver 
import HTMLParser,urllib2,urllib,re,os
import pymongo
import time
import sys  
reload(sys)  
sys.setdefaultencoding('utf-8')  
import pymongo  
def save_gif(url,name):
	try:
		urllib.urlretrieve(url, name)
	except Exception,e:
		print u'存贮失败,原因:',e
client = pymongo.MongoClient('localhost', 27017) 
print client.database_names()
db = client.GifDB
for table in  db.collection_names():
	print 'table name is ',table
	collection=db[table]
	for item in  collection.find():
		try: 
			if item['gif_final_url']:
				url,url_title= item['gif_final_url'],item['gif_title']
				gif_filename=table+'/'+url_title+'.gif'
				print 'start save %s, %s' % (url,gif_filename)
				save_gif(url,gif_filename)
		except Exception,e:
			print u'错误原因:',e

GitHub地址:

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

悟空资源网 网站程序 爬虫网站程序-Python爬虫(十九)爬取峰会网站——网络上常见的gif动画 https://www.wkzy.net/game/200749.html

常见问题

相关文章

官方客服团队

为您解决烦忧 - 24小时在线 专业服务