Python爬虫系列4-优化普通数据下载性能的速度

简介: 很多人在学习爬虫的时候,总是参照着书本中的内容或者是从网上学习的案例,但是那些案例你会,别人也会 ,如此怎么能提高我们的市场竞争力呢?Tony老师不服,于是,此篇文章顺利诞生;也是想让大家在学习的过程中真正的 **学以致用** 。

众所周知目前的互联网行业发展非常的激烈,在这个充满斗争的行业里,如果你想独树一帜,你想真正的在这里面有所作为,就必须得去折腾、去学习;而且是高效率的学习; 因为机会一定都是留给有准备的人的,但并不是说你想抓住就能抓的住的。需要我们付出很多精力和时间。

所以我们就需要不断提醒和逼迫自己去进步。因为过一个平凡无趣的人生实在太容易了,你可以不读书,不运动,不折腾。但是,人生最后悔的事情就是:我本可以。 💪

今天要抓取的目标是一个具有APP端的美图网站,为了方便大家的阅读及理解;整个代码的业务逻辑步骤我都已做了二次封装。

爬虫流程三部曲:

第一步:请求网络,获取服务器返回数据

第二步:处理数据,对获取到的数据进行解析,提取数据

第三步:将解析的内容进行存储

当我们确定好要抓取的网站目标时,按照传统方式大家也许直接就开始根据URL抓取数据下方数据了,但是今天咱们来玩儿点不一样的;
image.png

这里我在多次对网站测试的时候,发现本网站的数据是流动性的,什么意思呢?就是做了局部刷新的操作,会根据用户不断向下浏览的情况,不断的多次加载数据;当滑动至底端的时候,加载刷新了5次数据;这里引起了我的好奇

image.png

通过访问url,发现获取的是网站的原数据,它以json类型而存在
image.png

整理一下,发现其中几个字段很重要,以及图片的url也都在其中,如此,我就有了一个想法,既然数据是根据每一次的下滑而加载的,是不是我可以把url给动态的修改一下,当然这块属于前端知识,大家只需要知道可以这么做就行。事实证明是可以的。完全避开了大家通过selenium控制浏览器下滑刷新的办法。
image.png

首先这里我对url做了一次优化,我们发现,结构变了;
ps:因为数据太多就不展示了,有心的同学,可以尝试一下,不仅如此,我们发现网站的数据也更加有条理性,更加的清晰;给我的感觉也舒服了好多;

哈哈!可能是因为强迫症原因。。。不否认所有的程序员都有强迫症哈 😅

image.png

不过这样一来新的问题出现了;

我们所看到的网站url链接中是有中文存在的,那如果我直接填写一个中文可以吗?NO,这里我们需要对中文进行转码;Why ? 我们看一下这串字符 kw=%E8%B5%B5%E4%B8%BD%E9%A2%96

大家下意识的也许会认为它就是一串乱码,这里要纠正一下,实质上它不是乱码,它只是一个url编码,什么是url编码呢?其实从本质上讲就是一个ASCII码!大家也许奇怪了,什么情况,直接用中文它不香吗? 何必要换来换去的,其实这追溯到根源,很简单,因为计算机是老外发明的,所以人家根本不可能用中文去进行命名的;至此,相信大家应该也都能明白为什么了。

在了解完网站结构之后,二话不说,咱们先拿到数据再说,一切不以先拿到数据就去处理的行为都是耍流氓。 - 普门教育-Tony 😁

-实战

需要安装的库:
pip install requests

第一步:请求网络,获取数据

考虑到为了方便大家的阅读,所以在请求的时候我这里就直接给进行二次封装了。

import requests

# 通过 url 获取数据
def get_requests_page(url):
    # 请求网络 设置字符编码 将bytes进行转换
    page = requests.get(url).content.decode('utf-8')
    return page

第二步:解析并处理数据

处理数据的时候,我这里就不通过第三方的框架解析了,以一个最简单的str方式,给大家演示一遍。

除此之外也是可以通过别的方式进行解析,有心的同学可以自行尝试。

#第二步: 单个页面数据里通过查找字符串获取所有图片链接
def findall_in_page(page, startpart, endpart):
    all_strings = []
    #  向下查找 如果!=-1 就说明找到了
    while page.find(startpart, end) != -1:
        # 起始坐标 
        start = page.find(startpart, end) + len(startpart)
        # 结尾坐标 "
        end = page.find(endpart, start)
        # 切片
        string = page[start:end]
        all_strings.append(string)
    return all_strings

关键的地方我都通过注释的方式,给大家标注了,如果某地方不理解,可以在下方联系我进行咨询。

import urllib.parse

#第三步: 得到所有页面的 url ,分别得到各个数据
def pages_from_duitang(label):
    pages = []
    url = 'https://www.duitang.com/napi/blog/list/by_search/?kw={}&start={}&limit=1000'
    # 将中文转成 url 编码
    label = urllib.parse.quote(label)
    for index in range(0, 3600, 100):
        u = url.format(label, index)
        page = get_requests_page(u)
        pages.append(page)

image.png

#第四步: 获取所有页面的图片链接
def pic_urls_from_pages(pages):
    pic_urls = []
    for page in pages:
        urls = findall_in_page(page, 'path:"', '"')
        pic_urls.append(urls)
    return pic_urls

这里我们已经将所有需要的url全部解析出来了;至此,我们第二步的解析数据就完成了。
image.png

第三步:下载数据进行存储

#第五步: 通过 url 下载单张图片
def download_pics(url, name):
    r = requests.get(url)
    path = 'tony_pics/' + str(name) + '.jpg'
    with open(path, 'wb+') as file:
        file.write(r.content)

第四步:代码逻辑汇总、整合

# 第六步 : 总函数
def main(label):
    # 获取所有页面的数据
    pages = pages_from_duitang(label)
    # 获取所有图片的链接
    pic_urls = pic_urls_from_pages(pages)
    numbers = 0
    for url in pic_urls:
        numbers += 1
        print('正在下载第 {} 张图片'.format(numbers))
        download_pics(url, numbers)

第五步:效果展示


if __name__ == '__main__':
    main('赵丽颖')

普通数据下载速度

这里以下载数据时3秒计时为期限;可以看到数据已经下载至第24张图片。

image.png

接下来,核心点来了;我会对代码进行改造,在提高程序对数据下载的速度以外;还能对代码的性能进行优化。

这里我使用的方式是多线程;不否认除此之外还有更优的方案;大家可以自行尝试。

import threading

# 设置线程锁 
thread_lock = threading.BoundedSemaphore(value=10)
# 开启线程池
t = threading.Thread(target=download_pics, args=(url, numbers))
t.start()

优化之后的数据下载速度

运行效果的时间 这里以下载数据时3秒计时为期限;可以看到数据已经下载至第108张图片了。

这就是程序优化的魅力,所以大家在学习的过程中一定要有深度的学习,因为任何知识点如果大家只是学习了浅显的表面,是没有任何用处的。因为时间在变,互联网在变,我们若不想被淘汰只能去追赶;这就是互联网。。。

image.png

在这个浮躁的时代;竟然还有人能坚持篇篇原创;

如果本文对你学习有所帮助-可以点赞👍+ 关注!将持续更新更多新的文章。

支持原创。感谢!

相关文章
|
13天前
|
数据采集 缓存 Java
代理服务器调试技巧:优化Kotlin网络爬虫的数据抓取过程
代理服务器调试技巧:优化Kotlin网络爬虫的数据抓取过程
|
1天前
|
Python
小白入门必备!计科教授的Python精要参考PDF开放下载!
随着互联网产业的高速发展,在网络上早已积累了极其丰富的Python学习资料,任何人都可以基于这些资源,自学掌握 Python。 但实际上,网络上充斥的资源太多、太杂且不成体系,在没有足够的编程/工程经验之前,仅靠“看”线上资源自学,的确是一件非常困难的事。
|
4天前
|
数据采集 运维 API
适合所有编程初学者,豆瓣评分8.6的Python入门手册开放下载!
Python是一种跨平台的计算机程序设计语言,它可以用来完成Web开发、数据科学、网络爬虫、自动化运维、嵌入式应用开发、游戏开发和桌面应用开发。 Python上手很容易,基本有其他语言编程经验的人可以在1周内学会Python最基本的内容(PS:没有基础的人也可以直接学习,速度会慢一点)
|
4天前
|
数据采集 存储 C++
单线程 vs 多进程:Python网络爬虫效率对比
本文探讨了Python网络爬虫中的单线程与多进程应用。单线程爬虫实现简单,但处理速度慢,无法充分利用多核CPU。而多进程爬虫通过并行处理提高效率,更适合现代多核架构。代码示例展示了如何使用代理IP实现单线程和多进程爬虫,显示了多进程在效率上的优势。实际使用时还需考虑代理稳定性和反爬策略。
单线程 vs 多进程:Python网络爬虫效率对比
|
4天前
|
数据采集 存储 中间件
Python高效爬虫——scrapy介绍与使用
Scrapy是一个快速且高效的网页抓取框架,用于抓取网站并从中提取结构化数据。它可用于多种用途,从数据挖掘到监控和自动化测试。 相比于自己通过requests等模块开发爬虫,scrapy能极大的提高开发效率,包括且不限于以下原因: 1. 它是一个异步框架,并且能通过配置调节并发量,还可以针对域名或ip进行精准控制 2. 内置了xpath等提取器,方便提取结构化数据 3. 有爬虫中间件和下载中间件,可以轻松地添加、修改或删除请求和响应的处理逻辑,从而增强了框架的可扩展性 4. 通过管道方式存储数据,更加方便快捷的开发各种数据储存方式
|
5天前
|
数据采集 XML 前端开发
Python爬虫:BeautifulSoup
这篇内容介绍了Python中BeautifulSoup库的安装和使用。首先,通过在命令行输入`pip install bs4`进行安装,或使用清华源加速。接着讲解BeautifulSoup的基本概念,它是一个用于数据解析的工具,便于处理HTML和XML文档。与正则表达式不同,BeautifulSoup提供更方便的方式来查找和操作标签及其属性。 文章详细阐述了BeautifulSoup的两个主要方法:`find`和`find_all`。`find`方法用于查找单个指定标签,可结合属性字典进行精确选择;`find_all`则返回所有匹配标签的列表。通过这些方法,可以方便地遍历和提取网页元素。
15 0
|
5天前
|
数据采集 前端开发 JavaScript
Python爬虫入门
网络爬虫是自动抓取网页数据的程序,通过URL获取网页源代码并用正则表达式提取所需信息。反爬机制是网站为防止爬取数据设置的障碍,而反反爬是对这些机制的对策。`robots.txt`文件规定了网站可爬取的数据。基础爬虫示例使用Python的`urllib.request`模块。HTTP协议涉及请求和响应,包括状态码、头部和主体。`Requests`模块是Python中常用的HTTP库,能方便地进行GET和POST请求。POST请求常用于隐式提交表单数据,适用于需要发送复杂数据的情况。
15 1
小白入门必备!计算机科学教程的Python精要参考PDF开放下载!
随着互联网产业的高速发展,在网络上早已积累了极其丰富的Python学习资料,任何人都可以基于这些资源,自学掌握 Python。 但实际上,网络上充斥的资源太多、太杂且不成体系,在没有足够的编程/工程经验之前,仅靠“看”线上资源自学,的确是一件非常困难的事。
|
10天前
|
人工智能 Linux 开发工具
[oeasy]python018_ 如何下载github仓库_git_clone_下载仓库
在这个文档中,作者讨论了如何继续进行编程学习,特别是关于GitHub的使用。首先,回顾了从编写简单代码到管理大量代码的过程。然后,提到了通过“保存运行一条龙”操作来处理代码,以及GitHub作为全球最大的开源软件平台的重要性。在GitHub上,用户可以找到各种软件项目,包括Linux、Python和Blender等。 作者解释了GitHub的基本操作,如点赞(star)、 fork(复制项目)和watch(关注项目更新)。还介绍了如何下载项目到本地,通过`git clone`命令复制仓库的URL并将其粘贴到终端进行下载。如果遇到问题,可以尝试更换HTTP链接或等待一段时间重试。
191 1
|
10天前
|
API 开发工具 计算机视觉
华视 CVR-100UC 身份证读取 Python 二次开发(包含SDK下载地址)
华视 CVR-100UC 身份证读取 Python 二次开发(包含SDK下载地址)