美剧《权力的游戏》终于开播最后一季了, 在上周写了个简单的可视化美剧的爬虫软件来爬取美剧, 链接: https://www.cnblogs.com/weijiutao/p/10614694.html, 没想到真有小伙伴用了, 并且提出一个小建议, 爬取的链接是一个下载链接, 需要下载后才能观看, 希望能做一个可在线观看的. 然后就有了本篇.
话不多说, 先看运行结果:
跟之前的其实没多大区别, 有变化的是这次爬取的网站链接和内部需要重新做的爬取内容.
注: 由于本篇和上篇爬取流程大致相同, 所以本篇只是做简单的内容讲解, 想看详解流程的可移步上面的链接.
全部代码如下:
- import urllib.request
- from urllib import parse
- from lxml import etree
- import math
- 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)
- # 创建单行文本框
- self.textLineEdit = QLineEdit()
- # 创建一个按钮
- self.btnButton = QPushButton('确定')
- # 创建多行文本框
- self.textEdit = QTextEdit()
- # 实例化垂直布局
- layout = QVBoxLayout()
- # 相关控件添加到垂直布局中
- layout.addWidget(self.textLineEdit)
- layout.addWidget(self.btnButton)
- layout.addWidget(self.textEdit)
- # 设置布局
- self.setLayout(layout)
- # 将按钮的点击信号与相关的槽函数进行绑定, 点击即触发
- 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('utf-8'))
- # 请求发送的 url 地址
- url = "https://www.imeiju.cc/search.php?page=" + str(page) + "&searchword=" + name + "&searchtype="
- # 请求报头
- 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"}
- # 发送请求
- request = urllib.request.Request(url, headers=headers)
- # 获取请求的 HTML 文档
- HTML = urllib.request.urlopen(request).read()
- # 对 HTML 文档进行解析
- text = etree.HTML(HTML)
- # xpath 获取想要的信息
- numberTotal = text.xpath('//span[@class="text-color"][2]/text()')
- # 去掉总条数左右的引号
- numberTotal = numberTotal[0][1:][:-1]
- # 根据显示知道每页 10 条, 所以整除 10 并向上取整为总页数
- pageTotal = math.ceil(int(numberTotal) / 10)
- # 判断搜索内容是否有结果
- if pageTotal != 0:
- self.loadDetailPage(pageTotal, text, headers)
- # 搜索内容无结果
- else:
- self.infoSearchNull()
- # 加载点击搜索页面点击的本季页面
- def loadDetailPage(self, pageTotal, text, headers):
- # 获取每一季的内容 (剧名和链接)
- node_list = text.xpath('//div[@class="hy-video-details active clearfix"]//div[@class="head"]//a')
- items = {}
- items['name'] = self.textLineEdit.text()
- # 循环获取每一季的内容
- for node in node_list:
- # 获取信息
- title = node.xpath('text()')[0]
- link = node.xpath('@href')[0]
- items["title"] = title
- # 通过获取的单季链接跳转到本季的详情页面
- requestDetail = urllib.request.Request("https://www.imeiju.cc" + link, headers=headers)
- htmlDetail = urllib.request.urlopen(requestDetail).read()
- textDetail = etree.HTML(htmlDetail)
- node_listDetail = textDetail.xpath('//div[@class="panel clearfix"][1]//ul/li/a/@href')
- self.writeDetailPage(items, node_listDetail)
- # 爬取完毕提示
- if self.page == int(pageTotal):
- self.infoSearchDone()
- else:
- self.infoSearchContinue(pageTotal)
- # 将数据显示到图形界面
- 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'>https://www.imeiju.cc" +items['link'] + "</font>"
- "<p></p>"
- "</div>"
- )
- # 搜索不到结果的提示信息
- def infoSearchNull(self):
- QMessageBox.information(
- self, '提示', '搜索结果不存在, 请重新输入搜索内容',
- QMessageBox.Ok, QMessageBox.Ok
- )
- # 爬取数据完毕的提示信息
- def infoSearchDone(self):
- QMessageBox.information(
- self, '提示', '爬取《' + self.textLineEdit.text() + '》完毕',
- QMessageBox.Ok, QMessageBox.Ok
- )
- # 多页情况下是否继续爬取的提示信息
- def infoSearchContinue(self, pageTotal):
- end = QMessageBox.information(
- self, '提示', '爬取第' + str(self.page) + '页《' + self.textLineEdit.text() + '》完毕, 还有' + str(
- int(pageTotal) - self.page) + '页, 是否继续爬取',
- 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_())
能在本地运行 Python 的小伙伴直接复制粘贴上面的代码即可运行程序, 当然前提是 pip 所依赖的包.
本次我们要爬取的网站是 爱美剧 https://www.imeiju.cc/ , 具体的操作流程和上一篇差不多是一样的, 这里我们就简单的说一下流程:
我们在官网右上角搜索我们想要看的美剧:
然后就能进入我们想要看的美剧列表了:
和美剧天堂一样, 浏览器的 url 地址仍然不是我们想要的, 我们依旧可以点击页面下方的页面跳转来获取真正的 url 链接:
https://www.imeiju.cc/search.php?page=1&searchword=权力的游戏&searchtype=
这样我们就可以根据上面的 url 链接里的请求参数 page 和 searchword 来开始爬去我们的数据了, 然后就是根据 xpath 对页面进行元素查找, 获取要跳转的链接, 再进入跳转的链接里就可以获取我们想要看的美剧链接了.
需要注意的是当我们跳转到我们想看的链接, 比如上面的 《权力的游戏第四季》
我们发现上面不仅有在线播放, 还有影片下载, 但是这次我们选择在线播放, 但是在线播放又有好几种播放器, 这里本人只取了第一种播放第一种播放源, 也就是百度云播, 完全是没问题的, 如果大家觉得都想获取的请自行复制上面的代码修改吧, 代码做了很详细的注释, 大家应该能看懂.
由于本人不是专门做 Python 的, 只是了解那么一点点, 上面的代码如有问题, 请各位大佬批评指正, 在此谢过!
好记性不如烂笔头, 特此记录, 与君共勉!
最后预祝 《权力的游戏》完美收官!
来源: https://www.cnblogs.com/weijiutao/p/10695319.html