Python3
+Windows
的环境,使用布隆过滤器确实不是一个很明智的选择,因为要么现成的模块不支持Windows
平台,要么就是只支持Python2
,要么就是对文件操作的支持不理想。经过不懈努力,找到一个叫做bloom_filter
的。
——布隆过滤器的使用,使用效果确实不错,先自己新建一个文件,然后每次打开,检查是否存在,不存在就添加,存在的话就不错什么处理了。这里面我做了两个布隆过滤的文件,并且做了两个判断,第一次是判断这个要下载的图片的url
是否已经存在(就是是否已经下载过了),如果下载过了,那就忽略,如果没有下载过,那么就下载;下载之后,对下载的文件进行sha1
的处理,然后拿这个sha1
去比对是否已经存在,这是防止在不同网站下载了同一张图片,如果不存在,说明这张图片是唯一的,但是不能保证这个图片的图像是没有重复的,因为只要修改了一点点的图片属性或信息,那么他们也会属于不同的图片。
——其次,是连接数据库的一些操作,这里用的是pymysql
,记得再初始化里面连接数据库,在close_spider
方法中关闭连接。
——中间的一些过程就是,判断路径是否存在,不存在就创建,存在就如何如何。这里面用了年月日的目录来存储下载的图片,是为了保证图片存储相对合理一些,而不是放在一个大文件夹中。
——这里的sha1
的处理用的是hashlib
的库。
——这里对同一组图片会有一个统一的标识。
——对图片进行了重命名,防止出现重复的时候它会自己命名。
——在数据库中的存储可以看出来,是将图片储存的路径dir
和名称name
是分开来的,这是为了防止以后图片的移动。
import pymysql
import urllib.request
import uuid
import datetime
import os
from bloom_filter import BloomFilter
import hashlib
class DesignhubPipeline(object):
def __init__(self):
self.conn = pymysql.connect(host="127.0.0.1", user="root", password="root", db="dlimg", charset='utf8mb4')
self.bf_urls = BloomFilter(max_elements=10000000,error_rate=0.001,filename="C:/Users/Eric/Downloads/dlimg/bloomfilter/img_urls.bf")
self.bf_sha1s = BloomFilter(max_elements=10000000,error_rate=0.001,filename="C:/Users/Eric/Downloads/dlimg/bloomfilter/img_sha1s.bf")
def process_item(self, item, spider):
if len(item["img_urls"]) == 0:
return item
for img_url in item["img_urls"]:
# check out whether this img_url exists
if img_url not in self.bf_urls:
self.bf_urls.add(img_url)
try:
base_dir = "C:\\Users\\Eric\\Downloads\\dlimg\\"
today = datetime.datetime.today().isoformat()
img_dir = base_dir + today[:4] + "\\" + today[5:7] + "\\" + today[8:10] + "\\"
if not os.path.exists(img_dir):
# create dir
os.makedirs(img_dir)
img_name = str(uuid.uuid1()) + ".jpg"
img_path = img_dir.replace("\\", "/") + img_name
opener = urllib.request.build_opener()
opener.addheaders = [('User-Agent','Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36'),
('Accept','text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8'),
('Refer','https://www.yatzer.com/'),
('Cache-Control','no-cache')]
urllib.request.install_opener(opener)
urllib.request.urlretrieve(img_url, img_path)
# check out whether this img_file exists
with open(img_path, "rb") as f:
sha1Obj = hashlib.sha1()
sha1Obj.update(f.read())
hashRs = sha1Obj.hexdigest()
if hashRs in self.bf_sha1s:
# print("删除文件")
os.remove(img_path)
else:
self.bf_sha1s.add(hashRs)
sql = "insert into `dl_img`(`IMG_ID`,`IMG_DIR`,`IMG_NAME`,`GROUP_ID`,`SOURCE_URL`,`CREATE_DATE`) values(%s, %s, %s, %s,%s, %s)"
with self.conn.cursor() as cursor:
cursor.execute(sql, (str(uuid.uuid1()), img_dir.replace("\\", "/"), img_name, str(item["group_id"]), item["source_url"], datetime.datetime.now()))
self.conn.commit()
except Exception as e:
pass
return item
def close_spider(self, spider):
self.conn.cursor().close()
self.conn.close()