整理ING

os.path.exists(img_name)(判断图片是否已经存在,如果存在就跳过)

很好的一篇爬虫实例:先保存下

用MongoDB数据库记录已下载过的地址

使用PyMongo模块

直接代码:代码网址:http://blog.csdn.net/xiexiecm/article/details/59029912

主程序:

#导入需要的包 
from bs4 import BeautifulSoup  
import os  
from BackClimb import down  
from pymongo import MongoClient  
import datetime  
 
#建立一个抓图类 
class mzitu():  
 
 #创建数据库调用函数 
 def __init__(self):  
        client = MongoClient()##与MongoDB建立链接,这是默认链接本地MongoDB数据库 
        db = client['meinvxiezhenji']##选择一个数据库 
 self.meizitu_collection = db['meizitu']##在meinvxiezhenji这个数据库中,选择一个集合 
 self.title = ''##用来保存页面主题 
 self.url = ''##用来保存页面地址 
 self.img_urls = []##初始化一个列表,用来保存图片地址 
 
 #主入口函数 
 def all_url(self,url):  
        html = down.get(url,3) ##调用request函数吧地址传进去,返回一个response 
        all_a = BeautifulSoup(html.text,'lxml').find('div',class_='all').find_all('a')##用Soup对象的find方法找标签先查找class为all的div标签,然后查找所有<a>标签。find_all是查找所有<a>标签 
 for a in all_a:  
            title = a.get_text()  
 self.title = title  ##将主题保存到self.title中 
 print(u'开始保存:',title)##提示保存XXX 
            path = str(title).replace('?','_')##设置名字变量,将?替换成_ 
 self.mkdir(path)##调用mkdir函数创建文件夹,path代表的是标题名 
            os.chdir('F:\mzitu\\'+path) ##改变工作路径 
            href = a['href']##取出<a>里面的href属性 
 self.url = href ##将页面地址保存到self.url中 
 if self.meizitu_collection.find_one({'主题页面':href}): ##判断这个主题是否已经在数据库中,不在就运行eles下的内容,在则忽略。 
 print(u'这个页面已经爬过了!')  
 else:  
 self.html(href)##调用html函数吧href参数传递过去,href是套图的地址 
 
 #设置一个函数处理套图地址获得图片的页面地址 
 def html(self,href):  
        html = down.get(href,3)##调用request函数把套图地址传进去,返回一个response 
        max_span = BeautifulSoup(html.text,'lxml').find_all('span')[10].get_text()##查找所有的<span>标签获取最后一个标签中的文本也就是最后一个页面了 
        page_num =0 ##这个当作计数器用,用来判断图片是否下载完毕 
 for page in range(1,int(max_span)+1):##用range产生页面序列 
            page_num = page_num+1 ##每for循环一次+1,当page_num等于max_span的时候,就证明我们在下载最后一张图片了 
            page_url = href + '/'+str(page)##手动拼接每一个页面地址 
 self.img(page_url,max_span,page_num)##调用img函数,把上面需要的两个变量,传递给下一个函数。 
 
 #设置一个函数处理图片页面地址获得图片的实际地址 
 def img(self,page_url,max_span,page_num):  
        img_html = down.get(page_url,3)##调用request函数把图片页面地址传进去,返回一个response 
        img_url = BeautifulSoup(img_html.text,'lxml').find('div',class_='main-image').find('img')['src']##用img_Soup对象的find方法找标签先查找class为main-image的div标签,然后查找<img>标签里面的src。 
 self.img_urls.append(img_url)##每一次for page in range(1,int(max_span)+1)获取到的图片地址都会添加到img_urls这个初始化的列表中 
 if int(max_span) == page_num:##传递下来的两个参数用上了,当max_span和page_num相等是,就是最后一张图片,最后一次下载图片并保存到数据库中。 
 self.save(img_url)  
            post = {##这是构造一个字典, 
 '标题':self.title,'主题页面':self.url,'图片地址':self.img_urls,'获取时间':datetime.datetime.now()  
            }  
 self.meizitu_collection.save(post)##将post中的内容写入数据库 
 print (u'插入数据库成功')  
 else: ##max_span 不等于page_num的时候执行下面这段 
 self.save(img_url)##调用save函数保存图片,把img_url地址传递过去 
 
 #设置一个保存图片的函数 
 def save(self,img_url):  
        name = img_url[-9:-4]##取url的倒数第四至第九位做图片的名字 
 print('开始保存:',img_url)  
        img = down.get(img_url,3)##调用request函数把图片地址传进去,返回一个response 
        f = open(name+'.jpg','ab')##写入多媒体文件必须要b这个参数 
        f.write(img.content)##多媒体文件要用conctent 
        f.close()##关闭文件对象 
 
 #创建一个函数用来创建文件夹 
 def mkdir(self,path):  
        path = path.strip() ##去除path前后空格 
        isExists = os.path.exists(os.path.join('F:\mzitu',path))##join将各部分合成一个路径名。os.path.exists判断后面的路径是否存在 
 if not isExists: ##如果为False,创建文件夹 
 print(u'创建了一个名字叫做',path,u'的文件夹!')  
            os.makedirs(os.path.join('F:\mzitu',path))##创建多层文件夹,用join合成单独的一个路径文件夹 
 return True 
 else:  
 print(u'名字叫做',path,u'的文件夹已经存在了!')  
 return False 
 # 
 # #创建获取网页response的函数并返回 
 # def request(self,url): 
 #     headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36'}#设置浏览器请求头 
 #     content = requests.get(url,headers=headers) ##使用requests中的get方法获取页面的内容,加上浏览器请求头 
 #     return content 
 
Mzitu = mzitu()  ##实例化 
#这就是入口! 
Mzitu.all_url('http://www.mzitu.com/all')  

下载模块:

import requests  
import re  
import random  
import time  
 
#创建一个反反爬的类 
class download:  
 def __init__(self):  
 
 self.iplist = [] ##初始化一个list用来存放获取到的ip 
        html = requests.get(' http://haoip.cc/tiqu.htm')##使用requests中的get方法获取页面的内容 
        iplistn = re.findall(r'r/>(.*?)<b',html.text,re.S)##正则表达式,表示从html中获取所有r/><b中的内容,re.S的意思是包括匹配包括换行符,findall返回的是列表 
 for ip in iplistn:  
            i = re.sub('\n','',ip)##利用re.sub替换方法,将\n替换为空 
 self.iplist.append(i.strip())##将两端去除空格后添加到上面的list里面 
 
 self.user_agent_list=[  
 "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/22.0.1207.1 Safari/537.1",  
 "Mozilla/5.0 (X11; CrOS i686 2268.111.0) AppleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.57 Safari/536.11",  
 "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.6 (KHTML, like Gecko) Chrome/20.0.1092.0 Safari/536.6",  
 "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.6 (KHTML, like Gecko) Chrome/20.0.1090.0 Safari/536.6",  
 "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/19.77.34.5 Safari/537.1",  
 "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.9 Safari/536.5",  
 "Mozilla/5.0 (Windows NT 6.0) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.36 Safari/536.5",  
 "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3",  
 "Mozilla/5.0 (Windows NT 5.1) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3",  
 "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_0) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1063.0 Safari/536.3",  
 "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1062.0 Safari/536.3",  
 "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1062.0 Safari/536.3",  
 "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3",  
 "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3",  
 "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.1 Safari/536.3",  
 "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/536.3 (KHTML, like Gecko) Chrome/19.0.1061.0 Safari/536.3",  
 "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/535.24 (KHTML, like Gecko) Chrome/19.0.1055.1 Safari/535.24",  
 "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/535.24 (KHTML, like Gecko) Chrome/19.0.1055.1 Safari/535.24" 
        ]  
 
 def get(self,url,timeout,proxy=None,num_retries=6):##给函数一个默认参数proxy为空,默认num_retries为6次 
        UA = random.choice(self.user_agent_list)##从user_agent_list中随机取出一个字符串。 
        headers = {'User_Agent':UA}##构造一个完整的User_Agent 
 
 if proxy == None:##当代理为空时,不使用代理获取response 
 try:  
 return requests.get(url,headers=headers)##返回一个requests.get的页面文件,调用随机的headers,服务器以为我们是真的浏览器了 
 except:##如果上面的代码执行报错则执行下面的代码 
 if num_retries >0: ##num_retries是限定的重试次数 
                    time.sleep(10) ##延迟10秒 
 print(u'获取网页出错,10s后将获取倒数第:',num_retries,u'次')  
 return self.get(url,timeout,num_retries-1)##调用自身,并减1,实现循环6次 
 else:  
 print(u'开始使用代理')  
                    time.sleep(10)  
                    IP = ''.join(str(random.choice(self.iplist)).strip())##将从self.iplist中随机获取的字符串处理成需要的格式。去除两边空格后,用join拼接? 
                    proxy = {'http':IP}  
 return self.get(url,timeout,proxy)##代理不为空的时候 
 
 else: ##当代理不为空 
 try:  
                IP = ''.join(str(random.choice(self.iplist)).strip())##将从self.iplist中随机获取的字符串处理成需要的格式。去除两边空格后,用join拼接? 
                proxy = {'http':IP}##构造成一个代理 
 return requests.get(url,headers=headers,proxies = proxy,timeout=timeout)##使用代理获取response 
 except:  
 if num_retries >0:  
                    time.sleep(10)  
                    IP = ''.join(str(random.choice(self.iplist)).strip())  
                    proxy = {'http':IP}  
 print(u'正在更换代理,10s后将重新获取倒数第',num_retries,u'次')  
 print(u'当前代理是:',proxy)  
 return self.get(url,timeout,proxy,num_retries-1)  
 else:  
 print(u'代理也不好使!取消代理')  
 return self.get(url,3)  
 
down = download()  

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏C/C++基础

Linux命令(1)——xargs命令

xargs可以将stdin中以空格或换行符进行分隔的数据,形成以空格分隔的参数(arguments),传递给其他命令。因为以空格作为分隔符,所以有一些文件名或者...

1543
来自专栏武军超python专栏

2018年8月25日多线程编程总结

PYTHON 本身也支持多任务处理,并且提供了如下的操作方式 多线程多任务处理机制   (比较常用) 多进程多任务处理机制   (不常用,大型项目开发或者系...

1194
来自专栏破晓之歌

Python中os与sys两模块的区别 原

os: This module provides a portable way of using operating system dependent func...

681
来自专栏小筱月

shell 文本操作命令

:s/old/new/g 将当前行中查找到的所有字符串“old” 替换为“new”

1322
来自专栏xingoo, 一个梦想做发明家的程序员

cuda编程知识普及

本帖经过多方整理,大多来自各路书籍《GPGPU编程技术》《cuda高性能》 1 grid 和 block都可以用三元向量来表示: grid的数组元素是bloc...

3096
来自专栏北京马哥教育

138 条 Vim 命令、操作、快捷键全集

1876
来自专栏崔庆才的专栏

爬虫速度太慢?来试试用异步协程提速吧!

在执行一些 IO 密集型任务的时候,程序常常会因为等待 IO 而阻塞。比如在网络爬虫中,如果我们使用 requests 库来进行请求的话,如果网站响应速度过慢,...

4461
来自专栏WebDeveloper

跟我学习php文件和目录常用函数-下篇

1> bool mkdir ( string $pathname [, int $mode = 0777 [, bool $recursive = false ...

1051
来自专栏指尖下的Android

JNI之路径初探---3

这里讲一下如何拿到类中方法和属性的签名: 1,cmd进入命令行 2,cd 命令切到当前项目的src路径 3,javap -s -p 包名+类名(xxx.x...

1073
来自专栏java思维导图

Vim 命令、操作、快捷键(收藏大全)

以:和/开头的命令都有历史纪录,可以首先键入:或/然后按上下箭头来选择某个历史命令。

1073

扫码关注云+社区

领取腾讯云代金券