Python + PyQt5 實現美劇爬蟲可視工具(二)


美劇《權力的游戲》終於開播最后一季了,在上周寫了個簡單的可視化美劇的爬蟲軟件來爬取美劇,鏈接:https://www.cnblogs.com/weijiutao/p/10614694.html,沒想到真有小伙伴用了,並且提出一個小建議,爬取的鏈接是一個下載鏈接,需要下載后才能觀看,希望能做一個可在線觀看的。然后就有了本篇。

話不多說,先看運行結果:

跟之前的其實沒多大區別,有變化的是這次爬取的網站鏈接和內部需要重新做的爬取內容。

注:由於本篇和上篇爬取流程大致相同,所以本篇只是做簡單的內容講解,想看詳解流程的可移步上面的鏈接。

全部代碼如下:

  1 import urllib.request
  2 from urllib import parse
  3 from lxml import etree
  4 import math
  5 import ssl
  6 from PyQt5.QtWidgets import QApplication, QWidget, QLineEdit, QTextEdit, QVBoxLayout, QPushButton, QMessageBox
  7 import sys
  8 
  9 # 取消代理驗證
 10 ssl._create_default_https_context = ssl._create_unverified_context
 11 
 12 class TextEditMeiJu(QWidget):
 13     def __init__(self, parent=None):
 14         super(TextEditMeiJu, self).__init__(parent)
 15         # 定義窗口頭部信息
 16         self.setWindowTitle('愛美劇')
 17         # 定義窗口的初始大小
 18         self.resize(500, 600)
 19         # 創建單行文本框
 20         self.textLineEdit = QLineEdit()
 21         # 創建一個按鈕
 22         self.btnButton = QPushButton('確定')
 23         # 創建多行文本框
 24         self.textEdit = QTextEdit()
 25         # 實例化垂直布局
 26         layout = QVBoxLayout()
 27         # 相關控件添加到垂直布局中
 28         layout.addWidget(self.textLineEdit)
 29         layout.addWidget(self.btnButton)
 30         layout.addWidget(self.textEdit)
 31         # 設置布局
 32         self.setLayout(layout)
 33         # 將按鈕的點擊信號與相關的槽函數進行綁定,點擊即觸發
 34         self.btnButton.clicked.connect(self.buttonClick)
 35 
 36     # 點擊確認按鈕
 37     def buttonClick(self):
 38         # 爬取開始前提示一下
 39         start = QMessageBox.information(
 40             self, '提示', '是否開始爬取《' + self.textLineEdit.text() + "",
 41                         QMessageBox.Ok | QMessageBox.No, QMessageBox.Ok
 42         )
 43         # 確定爬取
 44         if start == QMessageBox.Ok:
 45             self.page = 1
 46             self.loadSearchPage(self.textLineEdit.text(), self.page)
 47         # 取消爬取
 48         else:
 49             pass
 50 
 51     # 加載輸入美劇名稱后的頁面
 52     def loadSearchPage(self, name, page):
 53         # 將文本轉為 gb2312 編碼格式
 54         name = parse.quote(name.encode('utf-8'))
 55         # 請求發送的 url 地址
 56         url = "https://www.imeiju.cc/search.php?page=" + str(page) + "&searchword=" + name + "&searchtype="
 57         # 請求報頭
 58         headers = {
 59             "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36"}
 60         # 發送請求
 61         request = urllib.request.Request(url, headers=headers)
 62         # 獲取請求的 html 文檔
 63         html = urllib.request.urlopen(request).read()
 64         # 對 html 文檔進行解析
 65         text = etree.HTML(html)
 66         # xpath 獲取想要的信息
 67         numberTotal = text.xpath('//span[@class="text-color"][2]/text()')
 68         # 去掉總條數左右的引號
 69         numberTotal = numberTotal[0][1:][:-1]
 70         # 根據顯示知道每頁 10 條,所以整除 10 並向上取整為總頁數
 71         pageTotal = math.ceil(int(numberTotal) / 10)
 72         # 判斷搜索內容是否有結果
 73         if pageTotal != 0:
 74             self.loadDetailPage(pageTotal, text, headers)
 75         # 搜索內容無結果
 76         else:
 77             self.infoSearchNull()
 78 
 79     # 加載點擊搜索頁面點擊的本季頁面
 80     def loadDetailPage(self, pageTotal, text, headers):
 81         # 獲取每一季的內容(劇名和鏈接)
 82         node_list = text.xpath('//div[@class="hy-video-details active clearfix"]//div[@class="head"]//a')
 83         items = {}
 84         items['name'] = self.textLineEdit.text()
 85         # 循環獲取每一季的內容
 86         for node in node_list:
 87             # 獲取信息
 88             title = node.xpath('text()')[0]
 89             link = node.xpath('@href')[0]
 90             items["title"] = title
 91             # 通過獲取的單季鏈接跳轉到本季的詳情頁面
 92             requestDetail = urllib.request.Request("https://www.imeiju.cc" + link, headers=headers)
 93             htmlDetail = urllib.request.urlopen(requestDetail).read()
 94             textDetail = etree.HTML(htmlDetail)
 95             node_listDetail = textDetail.xpath('//div[@class="panel clearfix"][1]//ul/li/a/@href')
 96             self.writeDetailPage(items, node_listDetail)
 97         # 爬取完畢提示
 98         if self.page == int(pageTotal):
 99             self.infoSearchDone()
100         else:
101             self.infoSearchContinue(pageTotal)
102 
103     # 將數據顯示到圖形界面
104     def writeDetailPage(self, items, node_listDetail):
105         for index, nodeLink in enumerate(node_listDetail):
106             items["link"] = nodeLink
107             # 寫入圖形界面
108             self.textEdit.append(
109                 "<div>"
110                     "<font color='black' size='3'>" + items['name'] + "</font>" + "\n"
111                     "<font color='red' size='3'>" + items['title'] + "</font>" + "\n"
112                     "<font color='orange' size='3'>第" + str(index + 1) + "集</font>" + "\n"
113                     "<font color='green' size='3'>播放鏈接:</font>" + "\n"
114                     "<font color='blue' size='3'>https://www.imeiju.cc" +items['link'] + "</font>"
115                     "<p></p>"
116                 "</div>"
117             )
118 
119     # 搜索不到結果的提示信息
120     def infoSearchNull(self):
121         QMessageBox.information(
122             self, '提示', '搜索結果不存在,請重新輸入搜索內容',
123             QMessageBox.Ok, QMessageBox.Ok
124         )
125 
126     # 爬取數據完畢的提示信息
127     def infoSearchDone(self):
128         QMessageBox.information(
129             self, '提示', '爬取《' + self.textLineEdit.text() + '》完畢',
130             QMessageBox.Ok, QMessageBox.Ok
131         )
132 
133     # 多頁情況下是否繼續爬取的提示信息
134     def infoSearchContinue(self, pageTotal):
135         end = QMessageBox.information(
136             self, '提示', '爬取第' + str(self.page) + '頁《' + self.textLineEdit.text() + '》完畢,還有' + str(
137                 int(pageTotal) - self.page) + '頁,是否繼續爬取',
138                         QMessageBox.Ok | QMessageBox.No, QMessageBox.No
139         )
140         if end == QMessageBox.Ok:
141             self.page += 1
142             self.loadSearchPage(self.textLineEdit.text(), self.page)
143         else:
144             pass
145 
146 if __name__ == '__main__':
147     app = QApplication(sys.argv)
148     win = TextEditMeiJu()
149     win.show()
150     sys.exit(app.exec_())

能在本地運行 Python 的小伙伴直接復制粘貼上面的代碼即可運行程序,當然前提是 pip 所依賴的包。

本次我們要爬取的網站是 愛美劇 https://www.imeiju.cc/,具體的操作流程和上一篇差不多是一樣的,這里我們就簡單的說一下流程:

我們在官網右上角搜索我們想要看的美劇:

然后就能進入我們想要看的美劇列表了:

和美劇天堂一樣,瀏覽器的 url 地址仍然不是我們想要的,我們依舊可以點擊頁面下方的頁面跳轉來獲取真正的 url 鏈接:

https://www.imeiju.cc/search.php?page=1&searchword=%E6%9D%83%E5%8A%9B%E7%9A%84%E6%B8%B8%E6%88%8F&searchtype=

這樣我們就可以根據上面的 url 鏈接里的請求參數 page 和 searchword 來開始爬去我們的數據了,然后就是根據 xpath 對頁面進行元素查找,獲取要跳轉的鏈接,再進入跳轉的鏈接里就可以獲取我們想要看的美劇鏈接了。

需要注意的是當我們跳轉到我們想看的鏈接,比如上面的 《權力的游戲第四季》

我們發現上面不僅有在線播放,還有影片下載,但是這次我們選擇在線播放,但是在線播放又有好幾種播放器,這里本人只取了第一種播放第一種播放源,也就是百度雲播,完全是沒問題的,如果大家覺得都想獲取的請自行復制上面的代碼修改吧,代碼做了很詳細的注釋,大家應該能看懂。

 

由於本人不是專門做 Python 的,只是了解那么一點點,上面的代碼如有問題,請各位大佬批評指正,在此謝過!

好記性不如爛筆頭,特此記錄,與君共勉!

最后預祝 《權力的游戲》完美收官!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM