风尘岁月 发表于 2020-7-23 06:49:34

线程池如何使用

最近在着手写一只爬虫 但是速度慢的感人 所以我决定
用多线程写 写到一半发现这样写我的for循环就没用了{:10_266:}
所以 请在座的各位大佬指点一下线程池的食用方法{:10_256:}
写完后我会把结果放到论坛的{:10_254:}

zltzlt 发表于 2020-7-23 06:54:52

可以参考:

https://blog.csdn.net/m0_38011218/article/details/81938261
https://www.cnblogs.com/hailin2018/p/12420678.html
https://www.cnblogs.com/randomlee/p/10249338.html

风尘岁月 发表于 2020-7-23 06:58:45

zltzlt 发表于 2020-7-23 06:54
可以参考:

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


我就是因为这样写才导致for循环不起作用了

风尘岁月 发表于 2020-7-23 06:59:55

{:10_266:}

zltzlt 发表于 2020-7-23 07:06:15

把你的代码发上来看看

风尘岁月 发表于 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 #url https://xxxxxxxxxx...
            img_id = image_data # ID
            img_data = image_data #数据
            save(all_title=all_title, image_id = img_id, img_data = img_data)



if __name__ == '__main__':
    main(6300)





风尘岁月 发表于 2020-7-23 07:24:15

还没审过呢{:10_295:}{:10_323:}

nahongyan1997 发表于 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 #url https://xxxxxxxxxx...
      img_id = image_data # ID
      img_data = image_data #数据
      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)




风尘岁月 发表于 2020-7-23 09:27:50

nahongyan1997 发表于 2020-7-23 09:15
@风尘岁月 我修改了你的代码以实现你提出的问题的解决:

感谢大佬的帮助 速度已经飞起了{:10_256:}

nahongyan1997 发表于 2020-7-23 10:00:18

风尘岁月 发表于 2020-7-23 09:27
感谢大佬的帮助 速度已经飞起了

一秒八张不是开玩笑的

风尘岁月 发表于 2020-7-23 10:04:49

而且图片很适合宅男

风尘岁月 发表于 2020-7-23 10:11:15

nahongyan1997 发表于 2020-7-23 09:15
@风尘岁月 我修改了你的代码以实现你提出的问题的解决:

唯一的缺点就是:保存快到连文件管理都没了(可能有一些图片未保存进去)

nahongyan1997 发表于 2020-7-23 10:27:24

for循环里加点延迟

风尘岁月 发表于 2020-7-23 14:29:15

nahongyan1997 发表于 2020-7-23 10:00
一秒八张不是开玩笑的

加了还是没有用

nahongyan1997 发表于 2020-7-23 14:32:43

风尘岁月 发表于 2020-7-23 14:29
加了还是没有用

难道你没发现你下载的图片都没有后缀吗

风尘岁月 发表于 2020-7-23 14:33:15

这个我早就发现了 已经改好了啊

风尘岁月 发表于 2020-7-23 14:34:13

nahongyan1997 发表于 2020-7-23 14:32
难道你没发现你下载的图片都没有后缀吗

这个我早就发现了 在上传后我才发现的 现在的问题是有写保存成功 但是却没有(有几张)

风尘岁月 发表于 2020-7-23 14:35:38

nahongyan1997 发表于 2020-7-23 14:32
难道你没发现你下载的图片都没有后缀吗

我Q:732434975在论坛讨论这个我没法给你看实例

风尘岁月 发表于 2020-7-23 14:47:17

nahongyan1997 发表于 2020-7-23 14:32
难道你没发现你下载的图片都没有后缀吗

录个视频给你看 大佬
页: [1]
查看完整版本: 线程池如何使用