美剧《权力的游戏》终于开播最后一季了,在上周写了个简单的可视化美剧的爬虫软件来爬取美剧,链接: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 "" 110 "" + items['name'] + "" + "\n" 111 "" + items['title'] + "" + "\n" 112 "第" + str(index + 1) + "集" + "\n" 113 "播放链接:" + "\n" 114 "https://www.imeiju.cc" +items['link'] + "" 115 "" 116 "" 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 的,只是了解那么一点点,上面的代码如有问题,请各位大佬批评指正,在此谢过!
好记性不如烂笔头,特此记录,与君共勉!
最后预祝 《权力的游戏》完美收官!