需求场景:
需要爬取canvas上的课件内容,因为原始课件没有发,只能自己从录播视频中提取,好在界面上已经能够显示ppt图片了(右下角),但是无法/不能直接一次性获取所有图片(只能一张一张看),
如何下载并整理好所有的ppt图片,最好合并成一个pdf文件
指导思想:网页能够展示出来的内容,必定能够解析网页获取
一,开发者工具:
参考商务办公tips2:如何获取网页内嵌pdf文件-CSDN博客等
二,自动化脚本爬虫:
element见下,再network-》image中其实就能看到网页端所呈现的ppt图片
1,理解目标网站结构
任务目标:爬取该页面中所有的ppt大图(png)
首先以第一张ppt图片为例,
右键图片或文本-审查元素,或者按F12打开浏览器工具(开发人员工具),查看该页面的源代码
其实可以看到都是具有 pptImage-xxx****类的 div****元素(当然一个xxx id后面有很多张图)
当然,严格来讲,是要提取id="ppt-xxx",再然后下面id="pptImage-xxx",再然后紧接着的<img src链接>
意思是,该地址即为该图片的网址,我们只需要将这些图片的每个网址获取到,通过编写的Python程序自动根据提供的网址,依次下载这些图片。
而且图片尺寸固定1920x1080,
2,编程,设置爬取规则
原理:简单来讲,利用计算机快速的响应能力,做重复性的体力活,模拟人工浏览网页下载图片和复制文本的过程,然后批量化整理好,放置在相应的文件夹目录。
该网站结构简单,几乎没有对爬虫的门槛。
因此,只需要模仿普通用户访问该网站即可。
流程:
1.访问该网站
2.找到该图片/文本
3.下载该图片/文本
4.以一个产品名为文件夹名,创建文件夹目录
5.存放这些图片/文本
框架代码如下:
只是框架步骤,实际上是跑不动的,实际代码见github仓库中
GitHub - MaybeBio/web-scraper-spider-crawler
"""请求网页"""
"""导入请求网页库"""
import requests
#用于发送HTTP请求的Python库,发送GET、POST、PUT、DELETE等HTTP请求到服务器,并获取服务器的响应
import re
#用于正则表达式的Python库,使用正则表达式来匹配和提取字符串中的模式
import time
#用于处理时间的Python库,提供时间相关的函数和类,如获取当前时间、格式化时间、计算时间差等
import parsel
#用于解析HTML和XML文档的Python库,使用CSS选择器或XPath表达式来选择和提取HTML或XML文档中的元素
import os
#用于处理文件和目录的Python库,创建、删除、重命名、读取和写入文件和目录
#请求头文件,仿照浏览器访问的方式
headers = {
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36 QIHU 360EE'
}
#定义了一个字典headers,其中包含一个键值对。键是'user-agent',值是一个字符串,模拟了Chrome浏览器在Windows 10上的user agent。这用于使HTTP请求看起来像来自真实浏览器
all_IF_Url = ['https://oc.sjtu.edu.cn/courses/71832/external_tools/8329']
#选取地址池中的地址,逐个执行
for IF_Url in all_IF_Url:
print(IF_Url)
session = requests.Session()
response = session.get('https://oc.sjtu.edu.cn/courses/71832/external_tools/8329')
#response = requests.get(IF_Url, headers=headers)
#向指定的URL发送GET请求,并将响应存储在response变量中,使用requests库和headers字典发送GET请求,存储响应文本在html变量中
html = response.text
#获取响应文本,即网页的HTML代码,将响应文本存储在html变量中
print(html)
"""解析网页"""
#解析网页课程中的ppt图片
urls = re.findall(r'<div id="pptImage-([0-9]+)" class="el-image"><img src="(.*?)"', html)
print(urls)
#这个正则表达式是用来匹配HTML标签中的特定模式,一个HTML的div标签,里面包含了几个属性:
"""
这个正则表达式是用来匹配HTML标签中的特定模式,这是一个HTML的div标签,里面包含了几个属性:
id="pptImage-(\d+)":这是一个id属性,值是pptImage-后面跟着一个或多个数字(用(\d+)表示)。这个id属性是我们要匹配的关键部分。
class="el-image":这是一个class属性,值是el-image。
<img src="(.*?)":这是一个HTML的img标签,里面包含了一个src属性,值是我们要匹配的图片URL(用(.*?)表示)。
整个正则表达式的意思是:匹配一个div标签,里面包含了id属性值为pptImage-后面跟着一个或多个数字,并且class属性值为el-image,然后紧跟着一个img标签,里面包含了一个src属性值为我们要匹配的图片URL。
在这个正则表达式中,使用了几个特殊的符号:
(\d+):匹配一个或多个数字,并且将其作为一个组(用括号括起来)。
(.*?):匹配任意字符(包括空白字符),并且将其作为一个组(用括号括起来)。
.*?:匹配任意字符(包括空白字符),但是是非贪婪的(即匹配尽可能少的字符)。
总的来说,这个正则表达式是用来匹配一个特定的HTML标签模式,并且提取出其中的图片URL。
"""
selector = parsel.Selector(html)
#使用parsel库的Selector类来解析HTML代码,将HTML代码存储在selector变量中
"""保存图片"""
#根据产品名称创建目录
no_char_list = ['*', '|', ':', '?', '/', '<', '>', '"', '\\'] # 非法字符合集
dir_names = re.findall(r'<div class="title sle">(.*?)</div>', html)
#删掉非法字符
for dir_name in dir_names:
for char in no_char_list:
if char in dir_name:
dir_name = dir_name.replace(char, '')
#目录不存在,则创建
if not os.path.exists(dir_name):
os.mkdir(dir_name)
print(dir_name)
#如果文件不存在,则写入文件
Img_index = 1
#初始化一个变量Img_index,用于记录下载的图片数量,初始值为1
for url in urls:
time.sleep(0.01)
#对于较差的服务器,需要加入一个0.01秒的延迟访问,否则对方服务器可能爬崩
#在每次下载图片之前,暂停0.01秒。这是为了避免对服务器的访问频率太高,导致服务器崩溃
file_name = url.split('?')[0].split('/')[-1]
if not os.path.exists(dir_name + '/' + file_name):
#检查指定目录中是否已经存在该图片文件
try:
response = requests.get(url, headers=headers)
#尝试使用requests库发送一个GET请求到图片URL,获取图片内容。headers=headers表示使用之前定义的请求头
with open(dir_name + '/' + file_name, 'wb')as f:
f.write(response.content)
#打开指定目录中的图片文件,如果文件不存在,则创建一个新文件。'wb'表示以二进制写模式打开文件,并将图片内容的二进制数据写入文件
except Exception:
pass
#如果在下载图片过程中出现异常,则忽略异常,继续执行下面的代码
print('Picture ' + str(Img_index) + ' downloaded.')
Img_index += 1
其中因为要依据每一节课(注意是每一节课)的视频日期创建文件夹,所以原代码中需要创建日期格式
步骤:
明确自己要爬的数据/元素(文本、表格、图片等)
检查该元素的html标签,并且一定要清楚上下级标签层级关系(规划好正则表达式+自己清楚树状结构)
按照框架写脚本,逐步调试细节
目的:
依据每一节课的日期来创建文件夹,然后将该节课的所有课件ppt的图片文件都爬下来,最后对每个文件夹的文件做一个png2ppt/pdf转换同时合并。
首先母文件夹:也就是每一节课的日期,检查元素之后html标签是:
如果我们选择节次是第一次的课,
此时进入ppt界面,第一张ppt对应的html标签元素是
其实我们可以看到这第一张ppt是在标签div pptImage-0下面,然后直接母标签是image-wrapper,再上一层是ppt-0,可以看到下面同级的ppt-xxx
pptWrapper下面的ppt-xxx下面的image-wrapper下面的pptImage-yyy,紧接着的img src链接
再观察上级标签中是否有日期属性
再上一级是ppt-list-wrapper,再上一级的同级才有ppt、节次的按钮标签
一直上移到body标签,其实都没有看到日期的标签,不好归类。
总体而言是body------》body_right------》ivs-module-wrapper------》module-info-wrapper------》ppt-list-wrapper------》pptWrapper------》ppt-0------》image-wrapper------》pptImage-0等
另外查看节次(日期)信息,
结构层次见下:
可以发现同样是module-info-wrapper,但是层次其实是不一样的,所以基本上无法和ppt偶连起来,也就是无法简单的自动化到同步节次日期,再归类ppt
另外注意到:src获取的url中其实我们只需要.jpg?这一部分作为文件名
但在实际操作中,发现:
其实就是没有登入进去
三,使用辅助爬虫工具:
注意爬虫的主要英文名对应:web spider、crawler、Scraper(因为英文软件、插件居多)
1,爬虫客户端app:基本上是封装好了已经比较成熟成型的商品
一句话道理很简单:要么忍受免费版的自动化(要么自学),要么学会smart的充钱(tb上其实有很多成熟业务产业链)
例如八爪鱼等,
只能起到辅助作用,实际上是还是不能替代代码本身的自动化流程
2,爬虫软件/插件:更多是个人开发者维护中
爬虫软件还好说,但是大多数google上的爬虫插件其实是细化到嗅探爬取图片,或者是特定标签的文本,实际上是功能细化分离了
(1)easyspider
官网原址:易采集EasySpider:无代码可视化爬虫/浏览器自动化测试软件
B站地址:https://www.bilibili.com/video/BV1th411A7ey/? vd_source=00f11bdb0cf4cafcaf7d8413135e5bb7
按照github主页:
主要教程参考如下:
(2)web scraper
(3)Simplescraper --- a fast and free web scraper
(4)scrapegraphAI
GitHub - ScrapeGraphAI/Scrapegraph-ai: Python scraper based on AI
(5)Web Scraper - Free Web Scraping
评论区实际上有很多提示,比如说是个人使用建议以及教程等,可以开率使用之后参考
https://www.juetan.cn/tools/chrome-web-scrapper/
比较小白一点的教程参考:
(6)迷你派:
迷你派采集器-最简单自动化数据监控抓取_哔哩哔哩_bilibili
比较难用
(7)Data Scraper - Easy Web Scraping
https://chromewebstore.google.com/detail/data-scraper-easy-web-scr/nndknepjnldbdbepjfgmncbggmopgden
比较难用
(8)
https://chromewebstore.google.com/detail/scraper/mbigbapnjcgaffohmbkdlecaccepngjd
自己设置,比较难用
(9)
https://chromewebstore.google.com/detail/easy-scraper-one-click-we/cljbfnedccphacfneigoegkiieckjndh
反倒是出奇的好用:
步骤如下:我以uniprot蛋白质数据库中的蛋白CTCF为例,想要爬取
family&domains处的序列信息:整理成一个3列的csv文件即可
因为这个网站不需要登录,所以不像前面canvas那样难爬,直接用request库去爬即可,此处略,
如果使用封装好的爬虫步骤如下:
(上面⑤)
下载下来的csv文件是:
(10)instant data scraper
https://chromewebstore.google.com/detail/instant-data-scraper/ofaokhiedipichpaobibbnahnkdoiiah
不好用
(11)图片助手(ImageAssistant) 批量图片下载器
如果只是特化之后爬取图片的话,可以使用很多图片嗅探实际上就是图片爬虫的插件进行处理
可以在参考html元素的性质之后进行条件限制
需要在每一次点击进入新节次新课件的时候,重新点击该IA,并进行刷新,才能累加捕获图片
目前使用下来以instant、simple以及easy为主
easy scraper插件 》Simplescraper》instant