第三届青训营字节搜索引擎-悟空数据集爬取

243 阅读2分钟

这是我参与「第三届青训营 -后端场」笔记创作活动的第5篇笔记

写了一个简易版本的数据集爬取,为了提高爬取速度采用了多线程的方案,其中由于部分图片链接已经失效了,因此需要清理一下,就采用data_id来筛选出所有图片正常的图文数据集对应id

该方案在i7-7700hq的笔记本上,爬取50k全量数据集时间在5分钟,如果是1亿键值对数据集花费很长时间,建议采用多机器分布式爬取的方法,由于本人当前没有分布式的测试环境,因此只展示了单机下的爬取代码。

其中的lock加锁解锁部分是可以进行优化的,这里是为了看爬取过程的失效图片所以才加上的,这里优化一下也是可以增加很大的速度的,优化方案可以是delete_images设置多个维度,每次进来的文件自身id%你设置的数组数量,这样就不是只有1个delete_images在那里阻塞了,能大大提高速度,最后我们把所有的delete_images合并就可以了,能大大加快时间。

当然这就是虽然举的一个优化例子,大家可以根据自己的想法随意修改。

import pandas as pd
import requests
import threading
import time
import concurrent.futures
import os


df=pd.read_csv('wukong50k_release.csv')
df['data_id'] = ''
for i in range(len(df)):
    df['data_id'][i] = i
urls = df['url']

path = r'images/'

delete_images = []
headers = {
    'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36 QIHU 360SE'
}

lock = threading.Lock()

def save(img_url, img_name):
    r = requests.request('get', img_url, headers=headers)  #获取网页
    if r.status_code != 200:
        lock.acquire()
        print(img_name, "Error", r.status_code)
        delete_images.append(int(img_name))
        print(delete_images)
        lock.release()
    else:
        with open(path + img_name + '.jpg','wb') as f:
            f.write(r.content)
        f.close()
        # 这里不用加锁
        # lock.acquire()
        print(img_name, "ok")
        # lock.release()

time_1 = time.time()
exe = concurrent.futures.ThreadPoolExecutor(max_workers=20)
for i in range(len(urls)):
    exe.submit(save, urls[i], str(i))
exe.shutdown()
time_2 = time.time()
use_time = int(time_2) - int(time_1)
print(f'总计耗时:{use_time}秒')

# 这个wukong2.csv和wukong.csv含义是一样的
for i in range(len(delete_images)):
    delete_images[i] = int(delete_images[i])
df.drop(delete_images, inplace=True)
df.to_csv("wukong2.csv", index=False)