2021年第一份教程:网页数据爬虫抓包入门教程下

网页数据抓包入门教程下

首先非常感谢大家的肯定,我也非常高兴这次分享的知识能帮助到大家,我尽力写的详细且简单明了,让各位看官能看了以后有所收获;今天就是最后一小节了,多线程或多进程操作。

为什么网络数据采集要用爬虫?

我们操控计算机,访问一个又一个网页,需要采集大量的数据保存到文件;众所周知涉及到网络、磁盘IO的任务都是IO密集型任务,他们CPU资源消耗很少,基本上我们访问网页和保存的时候,大部分时间都在等待IO操作完成。所以我们可以在爬取网页时,一个页面在等待,我们就在它等待的时候再去打开其他页面,各去做各的,以提升CPU运行的效率。这种编程方式,我们叫他并发编程(让程序的多个部分能够一起开工)

并发编程分为:1 多线程 ; 2 多进程 ; 3 异步编程

多进程在需要复杂计算的时候非常推荐使用,因为cpu本身就是进行密集型任务计算的,在运算量足够大的时候,我们启动的cpu才能高负荷运转,不至于资源浪费

多线程适合做运算量并不大,但耗费时间的任务,也就是IO密集型任务,它的问题在于无法使用到cpu的多核特性,这里不做细讲,大家感兴趣可以搜一些相关文章阅读

异步编程我会在稍后用一个经典的银行取钱案例解析,这里不做多解释。

在我们爬取数据的时候,由于大多数时候都在等待,且计算量并不大,所以我们开多线程就可以了

启动线程的方式也非常简单,导入库,开一个线程,然后启动,就ok了

from threading import Thread
Thread().start()

这样我们就启动了一个线程了,可是这样的一个线程我们什么也做不了,因为它没有分配任务,我们把我们要启动的任务添加到线程中,也就是Thread(这个括号中).start(),就完成这项任务新开一个子线程操作了,但是这种方式由于我们在这样执行任务的时候,往往会不停的结束子线程,然后开启子线程,造成不必要的资源浪费,所以并不推荐,我们这里只做一个基本的了解,一般我们在遇到需要使用到多线程的时候,我们一般直接开一个储存线程的容器,定下线程的数量,用一个拿一个,用完把线程还到容器中,让这个线程可以继续被其他代码取用。(这种做法我们一般叫做池化技术)

线程池的创建方式也很简单导入线程池的库,然后创建线程池,定下池中线程数量就ok了

from concurrent.futures.thread import ThreadPoolExecutor
with ThreadPoolExecutor(max_workers=10)as fool:

这时,我们创建了一个线程池,将要在里面执行我们的耗时任务。为了提高负荷,我外接了一个端口,提取里面的链接,下载里面的图片

import requests


def download_picture(picture_url):
    resp = requests.get(picture_url)
    if resp.status_code == 200:
        filename = picture_url[picture_url.rfind('/') + 1:]
        with open(f'images/{filename}', 'wb') as file:
            file.write(resp.content)


for x in range(1,6):
    resp = requests.get(f'https://image.so.com/zjl?ch=beauty&sn={x*30}')
    data_dict = resp.json()
    for beauty_dict in data_dict['list']:
    	picture_url = beauty_dict['qhimg_url']
        download_picture(picture_url)

在这一个任务中,我们用requests库get了‘http://api.tianapi.com/meinv/index’这个端口,循环获取了5页图片,解析了这个端口给的链接,然后依次循环保存,这就是典型的单线程IO密集型任务,我们将耗费大量时间在请求等待网页中,假如某个网页卡住,我们要等待很久,cpu这时候的利用率会非常低,所以我们可以在这里开一个线程池,循坏请求网页的时候每个任务就去线程池拿一个线程,拿完了就等他们完成任务,再还回来,再开任务,再去拿线程。。。。

from concurrent.futures.thread import ThreadPoolExecutor   #导入线程池的模块
import requests    #导入requests库

def download_picture(picture_url):  #创建保存图片的函数
    resp = requests.get(picture_url)  #get图片地址
    if resp.status_code == 200:   #判断响应状态是否正确
        filename = picture_url[picture_url.rfind('/') + 1:]  #对链接切片,取最后一个/后的字符,作为文件名
        with open(f'images/{filename}', 'wb') as file:   #打开文件夹位置,传入文件名,操作类型设为w/b
            file.write(resp.content)  #写入网页数据(二进制)


with ThreadPoolExecutor(max_workers=16) as pool:   #创建一个16线程的线程池
    for x in range(1,6):   #循环6次获取端口连接
        resp = requests.get(f'https://image.so.com/zjl?ch=beauty&sn={x*30}')
        data_dict = resp.json()   #拿到链接数据
        for beauty_dict in data_dict['list']:    #取出list列表中的每一个字典
            picture_url = beauty_dict['qhimg_url']    #取出里面的链接
            pool.submit(download_picture, picture_url)   #将get图片链接的函数放在线程池中执行

这里我将get网页的操作放在线程池下,拿到链接,解析,最后用循环拿到图片链接,将get图片保存到电脑的操作放在线程中,就完成了下载的池化操作。我作了详细解析,各位可以逐步观看。

后面我将开启特别要点深化和中级教程,将前面的内容进行补充和扩展,各位学者按需学习取用。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值