zoukankan      html  css  js  c++  java
  • 多线程爬取与存储基础

    多线程

    用不了多核!IO密集优势更大(比如下载文件啊...)

    一般的python程序都是前台运行(主线程),即代表了顺序运行只有前面一个运行完毕后才能运行后面一个,但这样有时候会很浪费时间,比如下载两个数据第一个数据单独下载耗时t1而第二个单独下载耗时t2,时间是t1+t2,但是你将这个两个程序放入后台同时运行则时间时max(t1,t2),这似乎没什么但是数据一多优势就体现出来了

    线程之间无序但是共享全局变量(所以会有互斥锁这种东西)

    首先导入threading库
    
    import threading
    
    xxx.threading.Thread(target=yyy,args=) 创造一个以yyy函数为后台运行的名字叫xxx的线程,args是yyy函数的传入参数
    
    xxx.start()启动这个名字叫xxx的线程
    
    xxx.join()堵塞这个线程:等这个线程执行完毕在进行下一个语句

    lock=threading.Lock()
    
    lock.aquire()//上锁
    
    //code
    
    lock.release()//解锁

    多进程

    可以用多核!计算密集优势更大

    相比多线程开销大但是开发更稳定

    进程是操作系统进行资源分配的基本单位,一个程序运行至少有一个进程,进程里面可以创造多个线程,线程是依附在进程里面的,没有进程就没有线程。

    并且进程之间不共享全局变量

    from multiprocessing import Pool
    
    p=Pool()
    
    p.apply_async(get_part_ts, args=(the_number,)) 不按顺序 添加|执行 进程
    
    p.apply(...) 按顺序执行进程
    
    p.close() 关闭不在接受新的进程
    
    p.join()堵塞进程
    from multiprocessing import Process //这个也可以
    
    a=Process(name=,target=)//name可以指定改进程的name,target需要传入func
    
    a.start()
    
    a.join()
    
    a.terminate()//强行终止进程

    不过window和Linux|mac的不同,他运行的时候会拷贝一遍主进程的程序,如果不加if __name__=="__main__": 会导致无限递归并报错

    子进程的执行是无序的操作系统来决定顺序

    常见的存储与读取

    先介绍os库的两个函数

    os.path.exsist(path): 判断path路径是否存在返回bool值

    xxx=os.getcwd(): 获得当前工作目录的绝对地址

    写入文本(字符串)的代码|脚本

      

    import threading
    import os
    
    def write_file(path,data):
        '''
        :param path: 要写入文件的路径
        :param data:要写入文件的数据
        :return:
        '''
        f = open(path, 'wb')
        f.write(data.encode('utf-8'))
        f.close()
        print('文件成功写入')
    def get_path(name):
        '''
        :param name:输入文件名称
        :return:输出该文件的绝对路径
        '''
        os_path = os.getcwd()  # 获得当前文件夹的路径
        file_name = name+ '.txt'  # 输入新建文件的名称
        return os_path + '\' + file_name  # 得到绝对地址
    
    def construct_file(name,data):
        '''
            只用这个函数的话没有覆盖文件功能
            输入文件名称
        :param name:
        :return:
        '''
        path=get_path(name)
        if not os.path.exists(path):
            write_file(path,data)
        else:
            print('文件名称已存在')
            print('是否覆盖文件Y|N')
            if input()=='Y':
    
                print('成功覆盖文件')
                write_file(path,data)
                return 0
            else:
                print('请重新输入文件名...')
                return 1
        return 0
    def write_dataintofile(data):
        '''
        :param data:将data写入文件
        :return:无返回值
        '''
        print('请输入文件名...')
        while construct_file(input(),data) :
            pass

    一些我永远记不住的open,write操作的参数

    “rt” 只读打开一个文本文件,只允许读数据
    “wt” 只写打开或建立一个文本文件,只允许写数据
    “at” 追加打开一个文本文件,并在文件末尾写数据
    “rb” 只读打开一个二进制文件,只允许读数据
    “wb” 只写打开或建立一个二进制文件,只允许写数据
    “ab” 追加打开一个二进制文件,并在文件末尾写数据
    “rt+” 读写打开一个文本文件,允许读和写
    “wt+” 读写打开或建立一个文本文件,允许读写
    “at+” 读写打开一个文本文件,允许读,或在文件末追加数据
    “rb+” 读写打开一个二进制文件,允许读和写
    “wb+” 读写打开或建立一个二进制文件,允许读和写
    “ab+” 读写打开一个二进制文件,允许读,或在文件末追加数据

    图片的读取,下载

    from bs4 import BeautifulSoup
    import urllib.request
    from bs4 import UnicodeDammit
    if __name__=='__main__':
        url='https://misaka.design.blog/'
        user_agent={'user_agent':"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36"}
        req=urllib.request.Request(url,headers=user_agent)
        res=urllib.request.urlopen(url)
        doc=res.read()
        dammit=UnicodeDammit(doc,["utf-8","gbk"])
        doc=dammit.unicode_markup
        soup=BeautifulSoup(doc,"html.parser")
        data=soup.select("a[class='post-thumbnail'] img")
        #获得图片的url地址
        img=urllib.request.urlopen(data[0]['src'])
        imga=img.read()#读取地址里面的 某进制 数据
        print(imga)
    
        with open(r'imag1.jpg','wb') as f:#创建一个jpg文件
          f.write(imga)
        #以二进制写入图片文件的话就是下载图片

  • 相关阅读:
    【郑轻】[1749]Forceast!
    【郑轻】[1749]Forceast!
    【郑轻】[1754]Chowhound!Chowhound!!Chowhound!!!
    【郑轻】[1754]Chowhound!Chowhound!!Chowhound!!!
    【郑轻】[1750]Bean!
    【郑轻】[1750]Bean!
    【郑轻】[1000]整数A+B
    【郑轻】[1000]整数A+B
    【杭电】[1236]排名
    【杭电】[1236]排名
  • 原文地址:https://www.cnblogs.com/cherrypill/p/12407717.html
Copyright © 2011-2022 走看看