鱼C论坛

 找回密码
 立即注册
查看: 1464|回复: 18

[已解决]线程池如何使用

[复制链接]
发表于 2020-7-23 06:49:34 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
最近在着手写一只爬虫 但是速度慢的感人 所以我决定
用多线程写 写到一半发现这样写我的for循环就没用了
所以 请在座的各位大佬指点一下线程池的食用方法
写完后我会把结果放到论坛的
最佳答案
2020-7-23 09:15:29
本帖最后由 nahongyan1997 于 2020-7-23 09:20 编辑

@风尘岁月 我修改了你的代码以实现你提出的问题的解决:
#导包
import requests
# 这里要这样导入最好
from time import sleep
import os
import threading
import parsel


if not os.path.exists('image'):
    os.mkdir('image')


#base_url = 'https://anime-pictures.net/pictures/view_posts/0?lang=en'

headers = {
    'User-Agent':
        'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36'
}


def get(url,headers):
    '''请求数据'''
    response = requests.get(url,headers)
    html_data = response.text
    return html_data


def parsel_data(html_data):
    '''筛选数据'''
    selector = parsel.Selector(html_data)
    result_list = selector.xpath('//span[@class="img_block_big"]')

    for result in result_list:
        image_url = result.xpath('./a/picture/source/img/@src').extract_first()
        image_id = result.xpath('./a/picture/source/img/@id').extract_first()

        img_url = 'https:' + image_url #手动拼url

        all_title = img_url

        img_data = requests.get(url = all_title,headers = headers).content


        yield all_title,image_id,img_data


def save(all_title,image_id,img_data):
    '''保存数据'''
    try:
        with open('image\\' + image_id, mode='wb') as f:
            print('保存成功:', image_id)
            f.write(img_data)

    except:
        pass
        print('保存失败:', image_id,'(•́へ•́╬)')

# 这段代码不能用
# def sleep(time):
#     '''休眠'''
#     time.sleep(time)

# 使用多线程需要把你重复执行的部分单独写成一个函数
def start_save(base_url):
    lock.acquire()
    html_data = get(url=base_url,headers=headers)
    for image_data in parsel_data(html_data):
        all_title = image_data[0] #url https://xxxxxxxxxx...
        img_id = image_data[1] # ID
        img_data = image_data[2] #数据
        save(all_title=all_title, image_id = img_id, img_data = img_data)
    lock.release()
def main(page):
    for page in range(0,page + 1):
        print('###############正在下载第{}页数据###############'.format(page))
        if page > 0:
            print('休息一下')
            sleep(10)
        base_url = 'https://anime-pictures.net/pictures/view_posts/0?lang=en'.format(page)
        print(base_url)
        # 这里是多线程的开启方式,修改后速度有明显提升
        my_thread = threading.Thread(target=start_save,args=(base_url,))
        my_thread.setDaemon(True)
        my_thread.start()


if __name__ == '__main__':
    lock = threading.RLock()
    
    main(6300)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-7-23 06:54:52 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-7-23 06:58:45 | 显示全部楼层
zltzlt 发表于 2020-7-23 06:54
可以参考:

https://blog.csdn.net/m0_38011218/article/details/81938261

我就是因为这样写才导致for循环不起作用了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-7-23 06:59:55 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-7-23 07:06:15 | 显示全部楼层
把你的代码发上来看看
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-7-23 07:15:37 | 显示全部楼层
zltzlt 发表于 2020-7-23 07:06
把你的代码发上来看看
#导包
import requests
import time
import os
import threading
import parsel


if not os.path.exists('image'):
    os.mkdir('image')


#base_url = 'https://anime-pictures.net/pictures/view_posts/0?lang=en'

headers = {
    'User-Agent':
        'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36'
}


def get(url,headers):
    '''请求数据'''
    response = requests.get(url,headers)
    html_data = response.text
    return html_data


def parsel_data(html_data):
    '''筛选数据'''
    selector = parsel.Selector(html_data)
    result_list = selector.xpath('//span[@class="img_block_big"]')

    for result in result_list:
        image_url = result.xpath('./a/picture/source/img/@src').extract_first()
        image_id = result.xpath('./a/picture/source/img/@id').extract_first()

        img_url = 'https:' + image_url #手动拼url

        all_title = img_url

        img_data = requests.get(url = all_title,headers = headers).content


        yield all_title,image_id,img_data


def save(all_title,image_id,img_data):
    '''保存数据'''
    try:
        with open('image\\' + image_id, mode='wb') as f:
            print('保存成功:', image_id)
            f.write(img_data)

    except:
        pass
        print('保存失败:', image_id,'(•́へ•́╬)')


def sleep(time):
    '''休眠'''
    time.sleep(time)


def main(page):
    for page in range(0,page + 1):
        print('###############正在下载第{}页数据###############'.format(page))
        if page > 0:
            print('休息一下')
            sleep(10)
        base_url = 'https://anime-pictures.net/pictures/view_posts/0?lang=en'.format(page)
        html_data = get(url=base_url,headers=headers)
        for image_data in parsel_data(html_data):
            all_title = image_data[0] #url https://xxxxxxxxxx...
            img_id = image_data[1] # ID
            img_data = image_data[2] #数据
            save(all_title=all_title, image_id = img_id, img_data = img_data)



if __name__ == '__main__':
    main(6300)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-7-23 07:24:15 | 显示全部楼层
还没审过呢
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-7-23 09:15:29 | 显示全部楼层    本楼为最佳答案   
本帖最后由 nahongyan1997 于 2020-7-23 09:20 编辑

@风尘岁月 我修改了你的代码以实现你提出的问题的解决:
#导包
import requests
# 这里要这样导入最好
from time import sleep
import os
import threading
import parsel


if not os.path.exists('image'):
    os.mkdir('image')


#base_url = 'https://anime-pictures.net/pictures/view_posts/0?lang=en'

headers = {
    'User-Agent':
        'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36'
}


def get(url,headers):
    '''请求数据'''
    response = requests.get(url,headers)
    html_data = response.text
    return html_data


def parsel_data(html_data):
    '''筛选数据'''
    selector = parsel.Selector(html_data)
    result_list = selector.xpath('//span[@class="img_block_big"]')

    for result in result_list:
        image_url = result.xpath('./a/picture/source/img/@src').extract_first()
        image_id = result.xpath('./a/picture/source/img/@id').extract_first()

        img_url = 'https:' + image_url #手动拼url

        all_title = img_url

        img_data = requests.get(url = all_title,headers = headers).content


        yield all_title,image_id,img_data


def save(all_title,image_id,img_data):
    '''保存数据'''
    try:
        with open('image\\' + image_id, mode='wb') as f:
            print('保存成功:', image_id)
            f.write(img_data)

    except:
        pass
        print('保存失败:', image_id,'(•́へ•́╬)')

# 这段代码不能用
# def sleep(time):
#     '''休眠'''
#     time.sleep(time)

# 使用多线程需要把你重复执行的部分单独写成一个函数
def start_save(base_url):
    lock.acquire()
    html_data = get(url=base_url,headers=headers)
    for image_data in parsel_data(html_data):
        all_title = image_data[0] #url https://xxxxxxxxxx...
        img_id = image_data[1] # ID
        img_data = image_data[2] #数据
        save(all_title=all_title, image_id = img_id, img_data = img_data)
    lock.release()
def main(page):
    for page in range(0,page + 1):
        print('###############正在下载第{}页数据###############'.format(page))
        if page > 0:
            print('休息一下')
            sleep(10)
        base_url = 'https://anime-pictures.net/pictures/view_posts/0?lang=en'.format(page)
        print(base_url)
        # 这里是多线程的开启方式,修改后速度有明显提升
        my_thread = threading.Thread(target=start_save,args=(base_url,))
        my_thread.setDaemon(True)
        my_thread.start()


if __name__ == '__main__':
    lock = threading.RLock()
    
    main(6300)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-7-23 09:27:50 | 显示全部楼层
nahongyan1997 发表于 2020-7-23 09:15
@风尘岁月 我修改了你的代码以实现你提出的问题的解决:

感谢大佬的帮助 速度已经飞起了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-7-23 10:00:18 | 显示全部楼层
风尘岁月 发表于 2020-7-23 09:27
感谢大佬的帮助 速度已经飞起了

一秒八张不是开玩笑的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-7-23 10:04:49 | 显示全部楼层
而且图片很适合宅男
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-7-23 10:11:15 | 显示全部楼层
nahongyan1997 发表于 2020-7-23 09:15
@风尘岁月 我修改了你的代码以实现你提出的问题的解决:

唯一的缺点就是:保存快到连文件管理都没了(可能有一些图片未保存进去)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-7-23 10:27:24 | 显示全部楼层
for循环里加点延迟
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-7-23 14:29:15 | 显示全部楼层
nahongyan1997 发表于 2020-7-23 10:00
一秒八张不是开玩笑的

加了还是没有用
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-7-23 14:32:43 | 显示全部楼层

难道你没发现你下载的图片都没有后缀吗
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-7-23 14:33:15 | 显示全部楼层
这个我早就发现了 已经改好了啊
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-7-23 14:34:13 | 显示全部楼层
nahongyan1997 发表于 2020-7-23 14:32
难道你没发现你下载的图片都没有后缀吗

这个我早就发现了 在上传后我才发现的 现在的问题是有写保存成功 但是却没有(有几张)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-7-23 14:35:38 | 显示全部楼层
nahongyan1997 发表于 2020-7-23 14:32
难道你没发现你下载的图片都没有后缀吗

我Q:732434975  在论坛讨论这个我没法给你看实例
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-7-23 14:47:17 | 显示全部楼层
nahongyan1997 发表于 2020-7-23 14:32
难道你没发现你下载的图片都没有后缀吗

录个视频给你看 大佬
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-1-19 20:31

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表