吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 2305|回复: 8
收起左侧

[Python 转载] 多线程 爬取网页历史版本文件[源码]

[复制链接]
piazini 发表于 2022-1-30 19:49
本帖最后由 piazini 于 2022-1-30 20:00 编辑

小技巧:启动Python默认自带的http服务器(在那个目录启动,当前路径就http服务的/根目录)
Python3:
[Python] 纯文本查看 复制代码
python -m http.server 8000

Python2:
[Python] 纯文本查看 复制代码
python2 -m SimpleHTTPServer


Python3 "多线程爬取历史文件"代码:
[Python] 纯文本查看 复制代码
#!/usr/bin/env python3
#_*_ encoding:UTF-8 _*_
# DATE: 2022/01/20

import requests
from multiprocessing import Process,Queue
import time
import os,sys

## 文件版本
file_version = '1.0.2'

## 开始、结束日期
date_start = '0601'
date_end = '0531'

## 最大线程数。建议不超过”任务管理器--性能“里显示总数-1,
##      -1是保留一个进程给其他程序用,比如显示4个,4-1=3 
queue_maxsize = 2

## 全局变量
_list_month_day = []
global _flag_creat_count
_flag_creat_count = 0
global _flag_down_count
_flag_down_count = 0

## 检查设置的线程数是否超过CPU的数量
def check_cpu_count():
    os_cpu_count = os.cpu_count()
    if os_cpu_count < queue_maxsize:
        print("\n[ Warning ] CPU支持[%d]个线程,设置线程queue_maxsize=%d,建议设置[%d],小于CPU线程数。\n"\
        %(os_cpu_count,queue_maxsize,os_cpu_count-1))

## 判断date_start_month月有多少天,并设置date_start_month月的天数
def set_month_days(date_start_month):
    month = date_start_month
    ## 是31天的月份
    month_31day = "01030507081012"
    ## 是30天的月份
    month_30day = "04060911"

    ## 默认是28天
    day = 28
    ## 判断month_31day是否包含传入的month月份,为真,这月是31天
    if month in month_31day:
        day = 31
    ## 判断month_30day是否包含传入的month月份,为真,这月是30天
    elif month in month_30day:
        day = 30
    return day  
    
##  产生月和日
def add_month_day():
    date_start_month = date_start[0:2]
    date_start_day = date_start[2:4]
    ## 如果月的第一位是0则取第二位
    if date_start_month[:1] == "0":
        date_start_month = date_start_month[1:2]
    ## 如果日的第一位是0则取第二位
    if str(date_start_day)[:1] == "0":
        date_start_day = date_start_day[1:2]
        
    ## 循环产生月和日
    while True:
        ## 将上一次循环设置成int类型,转回str类型
        date_start_month = str(date_start_month)    
        date_start_day = str(date_start_day)
        
        ## 如果日等于1号,则月份减一,
        ##  并调用set_month_days函数,获取本月天数
        if date_start_day == "1":
            ## 月减一
            date_start_month = int(date_start_month) - 1
            date_start_day = set_month_days(str(date_start_month))
        else:
            ## 天减一
            date_start_day = int(date_start_day) - 1

        ##  month_day值:1.拼接月+日,不足两位,左补0
        ##              2.上面运算把月和日转成int型,拼接需要转str型
        month_day = "{:0>2}".format(eval(str(date_start_month))) + "{:0>2}".format(eval(str(date_start_day)))
        
        ## 将生成的月和日添加到全局变量列表中,方便其他类或方法使用
        global _list_month_day
        _list_month_day.append(month_day)
        
        ## 如果当前月日和设置的date_end相等,则退出while循环
        if date_end == month_day:
            break
    
## 生成访问的url连接
def create_url(q):
    global _flag_creat_count
    
    ## 调用生成日期函数
    add_month_day();
    
    ## 循环生成
    while True:
        ## 月日
        for m_day in _list_month_day:
            ## 小时
            for h in range(0,24):
                ## 分钟
                for m in range(0,59):
                    ## 拼接生成下载地址
                    # url = 'https://127.0.0.1:8000/' + file_version + '/2021' +'%s%02d%02d'%(m_day,h,m) + '/tv_' + file_version + '.apk'
                    url = 'http://127.0.0.1:8000/' + file_version + '/2021' +'%s%02d%02d'%(m_day,h,m) + '/tv_' + file_version + '.apk'
                    q.put(url)
                    _flag_creat_count = _flag_creat_count + 1
        break    
    print(f"总共放入{_flag_creat_count}个URL")
    return _flag_creat_count
            
def download_file(q):
    global _flag_down_count
    
    while True:
        url = q.get()
        print(f'正在连接: ' + url)
        r = requests.get(url)
        codes = r.status_code
        
        ## 访问网站返回值为200说明文件存在
        if codes == 200:
            print("找到文件: " + url )
            print(">>> 记录到sucess.txt文件中")
            ## 参数a,追加内容到文件中
            with open ('sucess.txt','a') as f:
                f.write(url + '\n')
    
if (__name__ == 'main') or (__name__ == '__main__'):
    ## 记录开始时间
    #t1 = time.time()
    ## 检查设置的线程数是否超过CPU的数量
    check_cpu_count();
    print("\n提示: 用Ctrl + C 结束脚本\n")
    print("创建{%d}个线程..." %queue_maxsize) 
    q = Queue(maxsize=queue_maxsize)
    c = Process(target=create_url,args=(q,))
    d = Process(target=download_file,args=(q,))
    d.start()
    c.start()
    #print("阻塞线程d")
    d.join()
    #print("阻塞线程c")
    c.join()
    ## 记录结束时间
    #t2 = time.time()
    #print(f"总耗时:{t2 -t1}")
    
    


脚本执行效果图:

py script

py script


Python Http服务日志:

Python http

Python http


还有个问题,多线程脚本启动后,设定链接访问完后,也只能手动用Ctrl+C手动停止,
希望大佬赐教,应该怎么改,能让脚本访问完链接后退出。
尝试用“标记flag”和“记录产生链接数和访问链接数相等时退出”也没成功

__EOF__

免费评分

参与人数 4吾爱币 +10 热心值 +4 收起 理由
mei251617 + 1 + 1 谢谢@Thanks!
苏紫方璇 + 7 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
没事路过 + 1 + 1 谢谢@Thanks!
Lucifer_BW + 1 + 1 热心回复!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

ych13846701169 发表于 2022-1-30 23:48
好,但是不会呀
cxb1998 发表于 2022-1-31 00:08
a3322a 发表于 2022-1-31 04:06
52896009 发表于 2022-1-31 12:52
但是不会呀
 楼主| piazini 发表于 2022-2-2 10:07

没关系,慢慢学
 楼主| piazini 发表于 2022-2-2 10:08
cxb1998 发表于 2022-1-31 00:08
这个有用诶 有的时候想找但是又没有记录了

是的,我也是因为有这个需求才写的这个
 楼主| piazini 发表于 2022-2-2 10:09
a3322a 发表于 2022-1-31 04:06
感谢分享,学习了

谢谢,互相学习
 楼主| piazini 发表于 2022-2-2 10:10

互相学习,慢慢来
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-25 09:25

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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