爬虫入门之爬取网页ppt成品及制作思路随笔

python爬虫入门实现爬取ppt随笔

先上源代码!(使用方法及成品展示在最后哦,请耐心看完)

from selenium import webdriver
import requests
from selenium.webdriver.common.by import By
import os,fitz,pprint
username = ''
password = ''
fpath = 'D:/ppt/高数ppt'
headers={'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36'}
baseurl = input('输入链接:')
driver = webdriver.Firefox()
driver.implicitly_wait(10)
driver.get(baseurl)
un = driver.find_element(By.CSS_SELECTOR,'#phone')
pwd = driver.find_element(By.CSS_SELECTOR,'#pwd')
lgin = driver.find_element(By.CSS_SELECTOR,'#loginBtn')
un.send_keys(username)
pwd.send_keys(password)
lgin.click()
def eachurl(locurl):
	driver.execute_script('window.open("'+locurl+'")')
	handles = driver.window_handles
	driver.switch_to.window(handles[-1])
	fname = driver.find_element(By.CSS_SELECTOR, '#mainid h1').text + '.pdf'
	driver.switch_to.frame('iframe')
	try:
		frame = driver.find_element(By.TAG_NAME, 'iframe')
		driver.switch_to.frame(frame)
	except:
		pass
	try:
		driver.switch_to.frame('panView')
	except:
		pass
	elems = driver.find_elements(By.CSS_SELECTOR, 'img[src*="http"]')
	urls = []
	for elem in elems:
		urls.append(elem.get_attribute('src'))
	pprint.pprint(urls)
	if len(urls)==0:
		return
	os.makedirs(fpath, exist_ok=1)
	os.chdir(fpath)
	doc = fitz.open()
	for i in range(len(urls)):
		r = requests.get(urls[i], headers=headers)
		with open(str('tmp') + '.png', 'wb') as f:
			f.write(r.content)
		imgdoc = fitz.open(f)
		pdfbytes = imgdoc.convert_to_pdf()
		pdf_name = str(i) + '.pdf'
		imgpdf = fitz.open(pdf_name, pdfbytes)
		doc.insert_pdf(imgpdf)
	doc.save(fname)
	os.remove(str('tmp') + '.png')
	doc.close()
	driver.close()
	urls.clear()
locelems = driver.find_elements(By.CSS_SELECTOR,'.leveltwo .clearfix a')
def operateurls(locelems):
	for locelem in locelems:
		newurl = locelem.get_attribute('href')
		print(newurl)
		eachurl(newurl)
		handles = driver.window_handles
		driver.switch_to.window(handles[0])
operateurls(locelems)
eachurl(baseurl)
driver.quit()

背景:

高数老师竟然不提前发ppt在qq群里!然而不预习听高数真的是一种煎熬,所以经过百般搜寻,在我们学校的资源平台上找到了高数ppt的资源。BUT!

如图所示,这个ppt被放在一个iframe框架里,并且没有下载的入口,而我并不想每次看ppt都要打开网页!于是我用浏览器自带的开发工具检查页面源代码,发现他放的都是ppt内容的png格式文件!

不过经过万能的bing搜索,发现python有fitz库,可以将png图片转化为pdf格式,这太方便啦!

所以理论上我们可以通过简单的爬虫来实现爬ppt这个功能,理论可行,实践开始!

爬取单个页面实现思路

导入如下模块:

from selenium import webdriver#自动化操纵浏览器 
from selenium.webdriver.common.by import By#路径选择器会用到
import requests#用于下载图片
import os#用于设定文件存放路径
import fitz#将png转化为pdf
import pprint#为了打印出来漂亮,输出哪些url被下载了

我们先得设置一下headers,避免网站把我们当作自动化机器人

headers={'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36'}

我们现在创建一个webdriver对象,我这里用的是火狐

#实例化出来webdriver对象
driver = webdriver.Firefox()
#设置最大等待时间,就是要是浏览器没反应最多10s就停止了
driver.implicitly_wait(10)
#进入url
driver.get(baseurl)

我们首先需要用webdriver进入该节ppt的网页查看链接,但是我们用自动化方式操作浏览器时先要进行登录,界面如下:

我们用find_element方法找到输入口和登录按钮,并且将设置好的用户名和密码用send_keys方法输进去,并且用click模拟点击登录按钮


un = driver.find_element(By.CSS_SELECTOR,'#phone')
pwd = driver.find_element(By.CSS_SELECTOR,'#pwd')
lgin = driver.find_element(By.CSS_SELECTOR,'#loginBtn')

un.send_keys(username)
pwd.send_keys(password)
lgin.click()

现在我们就进入了有该节ppt的网站了

由于ppt在iframe框架中,且经过检查有的不止一层,最多两层,所以用try-except结构来进入ppt所在的最里层

driver.switch_to.frame('iframe')
	try:
		frame = driver.find_element(By.TAG_NAME, 'iframe')
		driver.switch_to.frame(frame)
	except:
		pass
	try:
		driver.switch_to.frame('panView')
	except:
		pass

再找到存放png的所有网址存起来,并将含有链接的标签存起来,再用get_attribute方法获取src里的链接放进url中

elems = driver.find_elements(By.CSS_SELECTOR, 'img[src*="http"]')
urls = []
	for elem in elems:
		urls.append(elem.get_attribute('src'))

用fitz库转换png并且把转换的同一节pdf连一块,文件取名从网页的标题里可以找到

fname = driver.find_element(By.CSS_SELECTOR, '#mainid h1').text + '.pdf'
#fpath是保存pdf的路径是自己设置的
os.makedirs(fpath, exist_ok=1)
	os.chdir(fpath)
	doc = fitz.open()
	for i in range(len(urls)):
        #用request方法获取url,再用二进制的方式将url里的图片内容写入临时文件
		r = requests.get(urls[i], headers=headers)
		with open(str('tmp') + '.png', 'wb') as f:
			f.write(r.content)
		imgdoc = fitz.open(f)
		#转成pdf
		pdfbytes = imgdoc.convert_to_pdf()
		pdf_name = str(i) + '.pdf'
		imgpdf = fitz.open(pdf_name, pdfbytes)
        #插入pdf
		doc.insert_pdf(imgpdf)
	doc.save(fname)
    #将进行中转的临时文件删除
	os.remove(str('tmp') + '.png')
	doc.close()
    #再关闭当前页面
    driver。close()

爬取多个页面思路

我们发现高数的ppt在一个资源列表里,

经过检查浏览器元素,找到了列表的元素里的href链接

于是我们就可以将单个页面的思路进行扩充,即每次爬完列表中的一个链接,用seenium中操作窗口的手柄window_handles的switch_to.window()返回上一个窗口,继续进入列表的下一个链接,调用爬取单个页面的函数eachurl()爬取下一节课的ppt

#找到该页面列表中所有的url,再通过爬取单个页面的方式处理每个列表中的url
locelems = driver.find_elements(By.CSS_SELECTOR,'.leveltwo .clearfix a')
def operateurls(locelems):
	for locelem in locelems:
		newurl = locelem.get_attribute('href')
		print(newurl)
		eachurl(newurl)
		handles = driver.window_handles
		driver.switch_to.window(handles[0])

使用方法及成品展示

我们先要设置源码里的username和password,注意是超星课堂的,一般username是手机号

然后设置你要保存ppt的路径,源码里是d盘ppt里的高数ppt,可以自己改

我们只要将有章节列表的页面的网址完全复制下来,然后运行我们的python程序,按照提示粘贴刚刚复制的链接就可以啦

posted @ 2022-03-22 12:48  qzx712  阅读(1698)  评论(0编辑  收藏  举报