這裡向大家分享一下python爬蟲的一些應用,主要是用爬蟲配合簡單的GUI界面實現視頻,音樂和小說的下載器。今天就先介紹如何實現一個動態視頻下載器。 爬取電影天堂視頻 首先介紹的是python爬取電影天堂網站的視頻(包括電影,電視劇,綜藝等),主要是用selenium動態網頁技術加上簡單的爬蟲技術。 ...
這裡向大家分享一下python爬蟲的一些應用,主要是用爬蟲配合簡單的GUI界面實現視頻,音樂和小說的下載器。今天就先介紹如何實現一個動態視頻下載器。
爬取電影天堂視頻
首先介紹的是python爬取電影天堂網站的視頻(包括電影,電視劇,綜藝等),主要是用selenium動態網頁技術加上簡單的爬蟲技術。
(1)電影網站首頁面地址:https://www.dytt8.net/
(2)用到的技術:selenium模擬瀏覽器運行。
(3)首先要安裝配置selenium庫和不同瀏覽器和該庫配合的插件。這裡安裝配置的過程略過。
(4)然後我們用下麵的代碼打開首頁,並輸出該網頁的源碼:
def getSource(url): browser = webdriver.Chrome() browser.get(url) print(browser.page_source) browser.close()
(5)然後我們找到搜索對應的網頁元素標簽,以及選擇類型和立即搜索按鈕對應的標簽。
分別為:
(6)然後我們用下麵的代碼把用戶輸入的信息模擬放到瀏覽器上
由於未載入完畢會進入廣告頁面,因此有需要改進的地方,這時就需要延長載入時間。這裡有顯示等待和隱式等待,用簡單的隱式等待即可。
有時候會出現錯誤,因為掩蓋的div可能會在進行一些操作後,會消失,比如頁面還在loading中。這時候點擊元素的話,就直接點擊在loading的標簽上,所以在這個操作前可以加個等待,讓掩蓋的div自行消失後,再等待左側菜單到可點擊狀態即可;或者進行刷新的操作,此div即可消失,再等待左側菜單到可點擊狀態即可。
代碼為:
def putUserMessger(url,this_name,this_type): ''' :param url: 瀏覽器網址 :param this_name: 需要下載的視頻名 :param this_type: 需要下載的視頻類型 ''' this_browser = webdriver.Chrome() this_browser.implicitly_wait(10) this_browser.get(url) # 把下載的視頻名和視頻類型進行模擬瀏覽器匹配 # 搜索輸入框的標簽屬性有name和class,這裡用name屬性進行獲取 this_browser.find_element_by_name('keyword').send_keys(this_name) time.sleep(2) # 選擇類型下拉框是html自帶的下拉框,不是input做的假的下拉框 Select(this_browser.find_element_by_name('field')).select_by_visible_text(this_type) time.sleep(2) # 點擊立即搜索按鈕,submit就不是單純的單擊,它會涉及到前後臺的交互 this_browser.find_element_by_name('Submit').click() this_browser.close() def main(): name = input('請輸入視頻名:') type = input('請選擇類型:') url = 'https://www.dytt8.net/' putUserMessger(url,name,type)
但是還是會出現下麵的問題:
selenium.common.exceptions.WebDriverException: Message: unknown error: Element <input name="Submit" type="Submit" value="立即搜索"> is not clickable at point (702, 220). Other element would receive the click: <div style="width: 1017px; height: 577px;"></div> (Session info: chrome=73.0.3683.86) (Driver info: chromedriver=73.0.3683.68 (47787ec04b6e38e22703e856e101e840b65afe72),platform=Windows NT 10.0.17134 x86_64)
但是我們發現我們點擊後的其實是有規律的,因此用另一個方法。
(6)二層頁面配置參數及視頻三層地址輸出
我們先分析一下url:
分析第二層頁面地址為:
http://s.ygdy8.com/plus/so.php?typeid=1&keyword=%C4%E3%B5%C4%C3%FB%D7%D6
是由http://s.ygdy8.com/plus/so.php?+typeid=視頻編號&keyword=視頻名gdk編碼組成。因此需要先轉化漢字為網頁地址url的編碼。
用下麵的代碼就可以構建一個需要的網址:
def main(): name = input('請輸入視頻名:') type = input('請選擇類型:') ret = quote(name, encoding="gbk") dict = {'電影':'1','電視劇':'2','綜藝':'99','舊綜藝':'89','游戲':'19','動漫':'16'} url = 'http://s.ygdy8.com/plus/so.php?' + 'typeid=' + dict[type] + '&keyword=' + ret
然後我們分析一下網頁:
輸出所有的視頻信息和三級地址:
def putUserMessger(url): ''' :param url: 視頻網址 ''' this_browser = webdriver.Chrome() this_browser.get(url) # 用css選擇器選擇 input1 = this_browser.find_elements_by_css_selector('.co_content8 ul td a') for i in input1: print(i.text) print(i.get_attribute('href')) this_browser.close()
(7)三級網頁找到下載界面
下載的鏈接的位置是:
然後用request配合pyquery下載即可。
下載鏈接如下:
(8)完整代碼
這裡沒有用到資料庫,上面的代碼再配合界面,這裡只暫時沒有界面的代碼如下:
# encoding: utf-8 from selenium import webdriver from urllib.request import quote import requests from pyquery import PyQuery as pq from tkinter import * def putUserMessger(url): ''' :param url: 視頻網址 ''' last_url = {} this_browser = webdriver.Chrome() this_browser.get(url) # 用css選擇器選擇 input1 = this_browser.find_elements_by_css_selector('.co_content8 ul td a') for i in input1: #用字典保存視頻的名字與下載地址 last_url[i.text] = i.get_attribute('href') this_browser.close() return last_url def download(all_url): this_download = {} for name,url in dict.items(all_url): r = requests.get(url) r.encoding = r.apparent_encoding doc = pq(r.text) this_url = doc('#Zoom a') this_download[name] = this_url.attr('href') return this_download type = 0 name = 0 def myRadiobutton(): global type type = v.get() def my_all(): name = var.get() ret = quote(name, encoding="gbk") url = 'http://s.ygdy8.com/plus/so.php?' + 'typeid=' + str(type) + '&keyword=' + ret all_url = putUserMessger(url) result = download(all_url) print(result) # 創建一個主視窗,用於容納整個GUI程式 root = Tk() # 設置主視窗對象的標題欄 root.title("視頻下載器") L1 = Label(root, text="請選擇類型:") L1.pack(side = TOP) v = IntVar() Radiobutton(root, text='電影', variable=v, command=myRadiobutton,value=1).pack(anchor=W) Radiobutton(root, text='電視劇', variable=v, command=myRadiobutton,value=2).pack(anchor=W) Radiobutton(root, text='綜藝', variable=v, command=myRadiobutton,value=99).pack(anchor=W) Radiobutton(root, text='舊綜藝', variable=v, command=myRadiobutton,value=89).pack(anchor=W) Radiobutton(root, text='游戲', variable=v, command=myRadiobutton,value=19).pack(anchor=W) Radiobutton(root, text='動漫', variable=v, command=myRadiobutton,value=16).pack(anchor=W) var = StringVar() L2 = Label(root, text="請輸入視頻名") L2.pack(side = LEFT) E1 = Entry(root, bd=5,textvariable=var) E1.pack(side = RIGHT) B = Button(root, text="點我",command=my_all).place(x=120, y=80) # 顯示界面,進入主事件迴圈 root.mainloop()
結果如下: