Python打包多线程下载(windows)

目标网站:https://www.igdcc.com/4Kmeinv

 目标产出:抓取第一页中的所有图片。

网站分析:无任何反爬策略,适合新手熟悉相关包的使用。

导入第三方包、设置线程数

import os
import sys
import random
import time
import requests
import threading
from lxml import etree

real_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), '..')
max_connections = 10
pool_sema = threading.BoundedSemaphore(max_connections)

抓取网站第一页数据

def get_text(url):
    for i in range(3):
        try:
            resp = requests.get(url, timeout=10)
            if resp.status_code != 200:
                time.sleep(5)
                continue
            return resp.text
        except Exception as e:
            time.sleep(5)
    print('抓取失败:', url)

获取图片的url

def get_image_urls(text):
    if not text:
        return
    root = etree.HTML(text)
    a_lts = root.xpath('//*/div[@class="mt15 clearfix pic-auto pic-list"]/a')
    ret = []
    for a in a_lts:
        urls = a.xpath('.//@data-original')
        if urls:
            ret.append(urls[0])
    return ret

保存图片(增加线程锁)

def get_content(url):
    for i in range(3):
        try:
            resp = requests.get(url, timeout=10)
            if resp.status_code != 200:
                time.sleep(5)
                continue
            return resp.content
        except Exception as e:
            time.sleep(5)



def save_image(output_file, image_url):
    pool_sema.acquire()
    content = get_content(image_url)
    if not content:
        return
    with open(output_file, 'wb') as fw:
        fw.write(content)
    time.sleep(random.random())
    pool_sema.release()

主函数

def start():
    url = 'https://www.igdcc.com/4Kmeinv/'
    # output_dir = os.path.join(real_path, 'data')
    output_dir = os.path.join(os.path.dirname(sys.argv[0]), 'data')
    if not os.path.exists(output_dir):
        cmd = 'mkdir %s' % output_dir
        cmd = cmd.replace('/', '\\')
        os.system(cmd)
        print('数据目录创建成功:data')
    print('只会抓取第一页哦>_<')
    text = get_text(url)
    image_urls = get_image_urls(text)
    print('开始抓取图片~')
    thread_list = []
    for i in range(len(image_urls)):
        output_file = os.path.join(output_dir, str(i) + '.png')
        image_url = image_urls[i]
        th = threading.Thread(target=save_image, args=(output_file, image_url))
        thread_list.append(th)
    for th in thread_list:
        th.start()
    for th in thread_list:
        th.join()

打包成一个exe文件

1、安装pyinstaller:pip install -i http://mirrors.aliyun.com/pypi/simple pyinstaller

2、打开控制台,进入项目中,执行:pyinstaller -F .\src\spider.py -n app的名称

注意:指定你的主文件即可,打包中会自己去找到相关的文件

这个时候恭喜你,已经成功了。

3、代码中,关于真实路径以及最后的输出目录,我也是测试了一下,才发现最后输出的目录用当前的路径来做最好,而真实路径的用途主要用在导入自己写的包的时候。

4、你是windows打包出来的就只能是windows用,mac电脑就只能是mac用。

5、本次目标网站主要用学习Python中的相关技术,各位客官可以选择其他网站,修改get_image_urls函数中图片获取的方式就可以达到目的。

6、最后产出文件会和exe文件同一目录下的data目录中。

7、最后的exe文件,存在权限问题,如果在其他app的目录中,比如微信,执行会失败。将文件拉取到桌面可以正常运行。

更进一步

1、多线程跑失败的url怎么处理?怎么实现分布式抓取?多线程日志输出?

可以使用队列来完成,避免资源竞争

2、如果有反爬策略怎么处理?

需要根据具体网站来分析,通过放慢频率、js逆向、第三方插件(滑块、验证码等)、selenium等来完成验证。

无论任何时候,我们都应该在确保别人服务器正常的情况下获取数据,争取做一个有素质的客人。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值