最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python+PyQt5實現(xiàn)美劇爬蟲可視工具的方法

 更新時間:2019年04月25日 10:03:55   作者:豐寸  
這篇文章主要介紹了Python+PyQt5實現(xiàn)美劇爬蟲可視工具的方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

美劇《權力的游戲》終于要開播最后一季了,作為馬丁老爺子的忠實粉絲,為了能夠看得懂第八季復雜龐大的劇情架構,本人想著將前幾季再穩(wěn)固一下,所以就上美劇天堂下載來看,可是每次都上去下載太麻煩了,于是干脆自己寫個爬蟲爬下來得了。

話不多說,先上圖片。

本人才疏學淺,就寫了個簡單的可視化軟件,關鍵是功能實現(xiàn)就行了嘛。

實現(xiàn)語言:Python ,版本 3.7.1

實現(xiàn)思路:首先運用 Python 工具爬取到數(shù)據(jù)再實現(xiàn)圖形化軟件。

由于這里只是實現(xiàn)簡單的爬取數(shù)據(jù),并沒有牽扯到 cookie 之類的敏感信息,也沒有設置代理,所以在選擇 Python 庫上并沒有引入 Selenium 或者更高級的 Scrapy 框架,只是拿到數(shù)據(jù)就可以了,沒必要那么麻煩。

所以選擇了 urllib 這個庫,在 Python 2.X 中應該是 urllib 和 urllib2 同時引入,由于本人選用的版本的 Python 3.X ,在 Python 3.X 中上面兩個庫已經(jīng)被合并為 urllib 一個庫,語法上有些不同,但語言這種東西都是大同小異的嘛。

先貼代碼,緩和一下尷尬的氣氛。

import urllib.request
from urllib import parse
from lxml import etree
import ssl
from PyQt5.QtWidgets import QApplication, QWidget, QLineEdit, QTextEdit, QVBoxLayout, QPushButton, QMessageBox
import sys

# 取消代理驗證
ssl._create_default_https_context = ssl._create_unverified_context

class TextEditMeiJu(QWidget):
 def __init__(self, parent=None):
  super(TextEditMeiJu, self).__init__(parent)
  # 定義窗口頭部信息
  self.setWindowTitle('美劇天堂')
  # 定義窗口的初始大小
  self.resize(500, 600)
  # 創(chuàng)建單行文本框
  self.textLineEdit = QLineEdit()
  # 創(chuàng)建一個按鈕
  self.btnButton = QPushButton('確定')
  # 創(chuàng)建多行文本框
  self.textEdit = QTextEdit()
  # 實例化垂直布局
  layout = QVBoxLayout()
  # 相關控件添加到垂直布局中
  layout.addWidget(self.textLineEdit)
  layout.addWidget(self.btnButton)
  layout.addWidget(self.textEdit)
  # 設置布局
  self.setLayout(layout)
  # 將按鈕的點擊信號與相關的槽函數(shù)進行綁定,點擊即觸發(fā)
  self.btnButton.clicked.connect(self.buttonClick)

 # 點擊確認按鈕
 def buttonClick(self):
  # 爬取開始前提示一下
  start = QMessageBox.information(
   self, '提示', '是否開始爬取《' + self.textLineEdit.text() + "》",
   QMessageBox.Ok | QMessageBox.No, QMessageBox.Ok
  )
  # 確定爬取
  if start == QMessageBox.Ok:
   self.page = 1
   self.loadSearchPage(self.textLineEdit.text(), self.page)
  # 取消爬取
  else:
   pass

 # 加載輸入美劇名稱后的頁面
 def loadSearchPage(self, name, page):
  # 將文本轉為 gb2312 編碼格式
  name = parse.quote(name.encode('gb2312'))
  # 請求發(fā)送的 url 地址
  url = "https://www.meijutt.com/search/index.asp?page=" + str(page) + "&searchword=" + name + "&searchtype=-1"
  # 請求報頭
  headers = {"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"}
  # 發(fā)送請求
  request = urllib.request.Request(url, headers=headers)
  # 獲取請求的 html 文檔
  html = urllib.request.urlopen(request).read()
  # 對 html 文檔進行解析
  text = etree.HTML(html)
  # xpath 獲取想要的信息
  pageTotal = text.xpath('//div[@class="page"]/span[1]/text()')
  # 判斷搜索內容是否有結果
  if pageTotal:
   self.loadDetailPage(pageTotal, text, headers)
  # 搜索內容無結果
  else:
   self.infoSearchNull()

 # 加載點擊搜索頁面點擊的本季頁面
 def loadDetailPage(self, pageTotal, text, headers):
  # 取出搜索的結果一共多少頁
  pageTotal = pageTotal[0].split('/')[1].rstrip("頁")
  # 獲取每一季的內容(劇名和鏈接)
  node_list = text.xpath('//a[@class="B font_14"]')
  items = {}
  items['name'] = self.textLineEdit.text()
  # 循環(huán)獲取每一季的內容
  for node in node_list:
   # 獲取信息
   title = node.xpath('@title')[0]
   link = node.xpath('@href')[0]
   items["title"] = title
   # 通過獲取的單季鏈接跳轉到本季的詳情頁面
   requestDetail = urllib.request.Request("https://www.meijutt.com" + link, headers=headers)
   htmlDetail = urllib.request.urlopen(requestDetail).read()
   textDetail = etree.HTML(htmlDetail)
   node_listDetail = textDetail.xpath('//div[@class="tabs-list current-tab"]//strong//a/@href')
   self.writeDetailPage(items, node_listDetail)
  # 爬取完畢提示
  if self.page == int(pageTotal):
   self.infoSearchDone()
  else:
   self.infoSearchContinue(pageTotal)

 # 將數(shù)據(jù)顯示到圖形界面
 def writeDetailPage(self, items, node_listDetail):
  for index, nodeLink in enumerate(node_listDetail):
   items["link"] = nodeLink
   # 寫入圖形界面
   self.textEdit.append(
    "<div>"
     "<font color='black' size='3'>" + items['name'] + "</font>" + "\n"
     "<font color='red' size='3'>" + items['title'] + "</font>" + "\n"
     "<font color='orange' size='3'>第" + str(index + 1) + "集</font>" + "\n"
     "<font color='green' size='3'>下載鏈接:</font>" + "\n"
     "<font color='blue' size='3'>" + items['link'] + "</font>"
     "<p></p>"
    "</div>"
   )

 # 搜索不到結果的提示信息
 def infoSearchNull(self):
  QMessageBox.information(
   self, '提示', '搜索結果不存在,請重新輸入搜索內容',
   QMessageBox.Ok, QMessageBox.Ok
  )

 # 爬取數(shù)據(jù)完畢的提示信息
 def infoSearchDone(self):
  QMessageBox.information(
   self, '提示', '爬取《' + self.textLineEdit.text() + '》完畢',
   QMessageBox.Ok, QMessageBox.Ok
  )

 # 多頁情況下是否繼續(xù)爬取的提示信息
 def infoSearchContinue(self, pageTotal):
  end = QMessageBox.information(
   self, '提示', '爬取第' + str(self.page) + '頁《' + self.textLineEdit.text() + '》完畢,還有' + str(int(pageTotal) - self.page) + '頁,是否繼續(xù)爬取',
   QMessageBox.Ok | QMessageBox.No, QMessageBox.No
  )
  if end == QMessageBox.Ok:
   self.page += 1
   self.loadSearchPage(self.textLineEdit.text(), self.page)
  else:
   pass


if __name__ == '__main__':
 app = QApplication(sys.argv)
 win = TextEditMeiJu()
 win.show()
 sys.exit(app.exec_())

以上是實現(xiàn)功能的所有代碼,可以運行 Python 的小伙伴直接復制到本地運行即可。都說 Python 是做爬蟲最好的工具,寫完之后發(fā)現(xiàn)確實是這樣。

我們一點點分析代碼:

import urllib.request
from urllib import parse
from lxml import etree
import ssl
from PyQt5.QtWidgets import QApplication, QWidget, QLineEdit, QTextEdit, QVBoxLayout, QPushButton, QMessageBox, QLabel
import sys

以上為我們引入的所需要的庫,前 4 行是爬取 美劇天堂 官網(wǎng)所需要的庫,后兩個是實現(xiàn)圖形化應用所需的庫。

我們先來看一下如何爬取網(wǎng)站信息。

由于現(xiàn)在 美劇天堂 使用的是 https 協(xié)議,進入頁面需要代理驗證,為了不必要的麻煩,我們干脆取消代理驗證,所以用到了 ssl 模塊。

然后我們就可以正大光明的進入網(wǎng)站了:

令人遺憾的是 url 鏈接為https://www.meijutt.com/search/index.asp,顯然沒有為我們提供任何有用的信息,當我們刷新頁面時,如下圖:

當我們手動輸入 ulr 鏈接https://www.meijutt.com/search/index.asp進行搜索時:

很明顯了,當我們在首頁輸入想看的美劇并搜索時網(wǎng)站將我們的請求表單信息隱藏了,并沒有給到 url 鏈接里,但是本人可不想每次都從首頁進行搜索再提交表單獲取信息,很不爽,還好本人發(fā)現(xiàn)了一個更好的方法。如下圖:

在頁面頂部有一個頁面跳轉的按鈕,我們可以選擇跳轉的頁碼,當選擇跳轉頁碼后,頁面變成了如下:

url 鏈接已經(jīng)改變了:https://www.meijutt.com/search/index.asp?page=&searchword=%C8%A8%C1%A6%B5%C4%D3%CE%CF%B7&searchtype=-1

我們再將 page 中動態(tài)添加為page=1,頁面效果不變。

經(jīng)過搜索多個不同的美劇的多次驗證發(fā)現(xiàn)只有 page 和 searchword 這兩個字段是改變的,其中 page 字段默認為 1 ,而其本人搜索了許多季數(shù)很長的美劇,比如《老友記》、《生活大爆炸》、《邪惡力量》,這些美劇也就一頁,但仍有更長的美劇,比如《辛普森一家》是兩頁,《法律與秩序》是兩頁,這就要求我們對頁數(shù)進行控制,但是需要特別注意的是如果隨意搜索內容,比如在搜索框只搜索了一個 ”i“,整整搜出了219頁,這要扒下來需要很長的時間,所以就需要對其搜索的頁數(shù)進行控制。

我們再來看一下 searchword 字段,將 searchword 字段解碼轉成漢字:

沒錯,正是我們想要的,萬里長征終于實現(xiàn)了第一步。

# 加載輸入美劇名稱后的頁面
def loadSearchPage(self, name, page):
 # 將文本轉為 gb2312 編碼格式
 name = parse.quote(name.encode('gb2312'))
 # 請求發(fā)送的 url 地址
 url = "https://www.meijutt.com/search/index.asp?page=" + str(page) + "&searchword=" + name + "&searchtype=-1"
 # 請求報頭
 headers = {"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"}
 # 發(fā)送請求
 request = urllib.request.Request(url, headers=headers)
 # 獲取請求的 html 文檔
 html = urllib.request.urlopen(request).read()
 # 對 html 文檔進行解析
 text = etree.HTML(html)
 # xpath 獲取想要的信息
 pageTotal = text.xpath('//div[@class="page"]/span[1]/text()')
 # 判斷搜索內容是否有結果
 if pageTotal:
  self.loadDetailPage(pageTotal, text, headers)
 # 搜索內容無結果
 else:
  self.infoSearchNull()

接下來我們只需要將輸入的美劇名轉化成 url 編碼格式就可以了。如上代碼,通過 urllib 庫對搜索的網(wǎng)站進行操作。

其中我們還需要做判斷,搜索結果是否存在,比如我們搜索 行尸跑肉,結果不存在。

當搜索結果存在時:

我們通過谷歌的 xpath 插件對頁面內的 dom 進行搜索,發(fā)現(xiàn)我們要選取的 class 類名。

我們根據(jù)獲取到的頁數(shù),找到所有頁面里我們要搜索的信息:

# 加載點擊搜索頁面點擊的本季頁面
def loadDetailPage(self, pageTotal, text, headers):
 # 取出搜索的結果一共多少頁
 pageTotal = pageTotal[0].split('/')[1].rstrip("頁")
 # 獲取每一季的內容(劇名和鏈接)
 node_list = text.xpath('//a[@class="B font_14"]')
 items = {}
 items['name'] = self.textLineEdit.text()
 # 循環(huán)獲取每一季的內容
 for node in node_list:
  # 獲取信息
  title = node.xpath('@title')[0]
  link = node.xpath('@href')[0]
  items["title"] = title
  # 通過獲取的單季鏈接跳轉到本季的詳情頁面
  requestDetail = urllib.request.Request("https://www.meijutt.com" + link, headers=headers)
  htmlDetail = urllib.request.urlopen(requestDetail).read()
  textDetail = etree.HTML(htmlDetail)
  node_listDetail = textDetail.xpath('//div[@class="tabs-list current-tab"]//strong//a/@href')
  self.writeDetailPage(items, node_listDetail)
 # 爬取完畢提示
 if self.page == int(pageTotal):
  self.infoSearchDone()
 else:
  self.infoSearchContinue(pageTotal)

我們根據(jù)獲取到的鏈接,再次通過 urllib 庫進行頁面訪問,即我們手動點擊進入其中的一個頁面,比如 權利的游戲第一季,再次通過 xpath 獲取到我們所需要的下載鏈接:

至此我們就將所有我們搜索到的 權力的游戲 的下載鏈接拿到手了,接下來就是寫圖形界面了。

本人選用了 PyQt5 這個框架,它內置了 QT 的操作語法,對于本人這種小白用起來也很友好。至于如何使用本人也都在代碼上添加了注釋,在這兒做一下簡單的說明,就不過多解釋了。

from PyQt5.QtWidgets import QApplication, QWidget, QLineEdit, QTextEdit, QVBoxLayout, QPushButton, QMessageBox, QLabel
import sys

將獲取的信息寫入搜索結果內:

# 將數(shù)據(jù)顯示到圖形界面
def writeDetailPage(self, items, node_listDetail):
 for index, nodeLink in enumerate(node_listDetail):
  items["link"] = nodeLink
  # 寫入圖形界面
  self.textEdit.append(
   "<div>"
    "<font color='black' size='3'>" + items['name'] + "</font>" + "\n"
    "<font color='red' size='3'>" + items['title'] + "</font>" + "\n"
    "<font color='orange' size='3'>第" + str(index + 1) + "集</font>" + "\n"
    "<font color='green' size='3'>下載鏈接:</font>" + "\n"
    "<font color='blue' size='3'>" + items['link'] + "</font>"
    "<p></p>"
   "</div>"
  )

因為可能有多頁情況,所以我們得做一次判斷,提示一下剩余多少頁,可以選擇繼續(xù)爬取或停止,做到人性化交互。

# 搜索不到結果的提示信息
def infoSearchNull(self):
 QMessageBox.information(
  self, '提示', '搜索結果不存在,請重新輸入搜索內容',
  QMessageBox.Ok, QMessageBox.Ok
 )

# 爬取數(shù)據(jù)完畢的提示信息
def infoSearchDone(self):
 QMessageBox.information(
  self, '提示', '爬取《' + self.textLineEdit.text() + '》完畢',
  QMessageBox.Ok, QMessageBox.Ok
 )

# 多頁情況下是否繼續(xù)爬取的提示信息
def infoSearchContinue(self, pageTotal):
 end = QMessageBox.information(
  self, '提示', '爬取第' + str(self.page) + '頁《' + self.textLineEdit.text() + '》完畢,還有' + str(int(pageTotal) - self.page) + '頁,是否繼續(xù)爬取',
  QMessageBox.Ok | QMessageBox.No, QMessageBox.No
 )
 if end == QMessageBox.Ok:
  self.page += 1
  self.loadSearchPage(self.textLineEdit.text(), self.page)
 else:
  pass

demo 圖形化軟件操作如下:

在搜索框內輸入要搜索的美劇名,點擊確認。提示一下是否要爬取,點擊 No 不爬取,點擊 OK 爬取。

判斷一下是否存在搜索結果,比如吧 ”辛普森一家“ 換成了 ”吉普森一家“,搜索內容不存在。

如果搜索內容存在,在搜索完成第一頁后提示一下是否需要繼續(xù)爬取,點擊 No 表示停止爬取,點擊 OK 表示繼續(xù)爬取。

最后爬取完畢后提示爬取完畢:

由于本人對 Python 了解不深,代碼中有很多不足之處,需要不斷學習改進,代碼中有任何要改進的地方請各位大佬批評指教!

最后本人做了一套包含 Mac 和 windows 版的圖形化美劇天堂抓包程序,只需要在對應電腦上點擊運行即可,需要的小伙伴可以在本人的公眾號后臺回復美劇天堂就可以拿到了,注:在 windows 上打包生成的 .exe 軟件第一打開時被 360 阻止,大家允許操作就可以了,Mac 無此提示。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關文章

  • python 生成xml文件,以及美化的實例代碼

    python 生成xml文件,以及美化的實例代碼

    這篇文章主要介紹了python 生成xml文件,以及美化的實例代碼,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-04-04
  • 詳解scrapy內置中間件的順序

    詳解scrapy內置中間件的順序

    這篇文章主要介紹了詳解scrapy內置中間件的順序,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-09-09
  • Python?Playwright進行常見的頁面交互操作

    Python?Playwright進行常見的頁面交互操作

    在使用?Playwright?進行?Web?自動化時,頁面交互是核心操作之一,本文將詳細介紹如何使用?Playwright?進行常見的頁面交互操作,希望對大家有所幫助
    2024-10-10
  • OPENCV去除小連通區(qū)域,去除孔洞的實例講解

    OPENCV去除小連通區(qū)域,去除孔洞的實例講解

    今天小編就為大家分享一篇OPENCV去除小連通區(qū)域,去除孔洞的實例講解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-06-06
  • matplotlib實現(xiàn)顯示偽彩色圖像及色度條

    matplotlib實現(xiàn)顯示偽彩色圖像及色度條

    今天小編就為大家分享一篇matplotlib實現(xiàn)顯示偽彩色圖像及色度條,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-12-12
  • python圖像處理之反色實現(xiàn)方法

    python圖像處理之反色實現(xiàn)方法

    這篇文章主要介紹了python圖像處理之反色實現(xiàn)方法,涉及Python結合OpenCV與numpy操作圖片的相關技巧,需要的朋友可以參考下
    2015-05-05
  • pandas.DataFrame的for循環(huán)迭代的實現(xiàn)

    pandas.DataFrame的for循環(huán)迭代的實現(xiàn)

    本文主要介紹了pandas.DataFrame的for循環(huán)迭代的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-02-02
  • Python、Javascript中的閉包比較

    Python、Javascript中的閉包比較

    這篇文章主要介紹了Python、Javascript中的閉包比較,本文分別講解了Python和Javascript中的閉包,分對它們的不同做了一個簡單的比較,需要的朋友可以參考下
    2015-02-02
  • Python中PySide2的安裝及配置

    Python中PySide2的安裝及配置

    在python中,支持圖形化界面開發(fā)的庫有很多,今天主要介紹一下PySide2這個庫。具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-07-07
  • Python字符串的創(chuàng)建和駐留機制詳解

    Python字符串的創(chuàng)建和駐留機制詳解

    字符串駐留是一種在內存中僅保存一份相同且不可變字符串的方法,本文重點給大家介紹Python字符串的創(chuàng)建和駐留機制,感興趣的朋友跟隨小編一起看看吧
    2022-02-02

最新評論

嘉义市| 黄冈市| 温州市| 宣威市| 伊宁县| 临江市| 二连浩特市| 张家界市| 炉霍县| 大兴区| 五峰| 海林市| 长汀县| 遂昌县| 广州市| 安吉县| 油尖旺区| 乌什县| 屯门区| 马尔康县| 太仓市| 海淀区| 吐鲁番市| 新邵县| 霍城县| 池州市| 黑河市| 甘孜县| 育儿| 北辰区| 定兴县| 渭源县| 大庆市| 城口县| 丽江市| 吉木萨尔县| 苏尼特右旗| 普宁市| 唐山市| 古交市| 林州市|