爬蟲入門之爬取網頁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()
使用方法及成品展示
我們先要設定原始碼裡的username和password,注意是超星課堂的,一般username是手機號
然後設定你要儲存ppt的路徑,原始碼裡是d盤ppt裡的高數ppt,可以自己改
我們只要將有章節列表的頁面的網址完全複製下來,然後執行我們的python程式,按照提示貼上剛剛複製的連結就可以啦
背景:
高數老師竟然不提前發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])