首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何从tvdb抓取第三季的剧集编号?

如何从tvdb抓取第三季的剧集编号?
EN

Stack Overflow用户
提问于 2019-09-04 19:04:59
回答 1查看 136关注 0票数 1

我正在尝试从tvdb中分离并处理总的季集数量。作为一个简单的例子,我正在使用show LEGION (https://www.thetvdb.com/series/legion)。这个主页将显示该剧有多少季,在这一行的末尾,有一个徽章指示每一季的剧集数量。我想要一个剧集的“绝对数量”,所以我需要所有这些数字加在一起。我可以做到这一点,但是我想排除“特价”季的剧集数量,这是困难的部分。特别是因为这些元素的内部文本将在指示它所引用的季节之前显示徽章的值。

我已经经历了几个阶段。首先,我能够得到父标签的内部文本,这给了我一个信息块,说明了表中的所有内容,如下所示(似乎有两个标签具有相同的类名,这就是为什么我得到了双重结果。在这方面的任何帮助也将不胜感激)

2018年4月至2018年4月特价8

2017年第1季-2017年3月11

第二季2018年4月-2018年6月8

第三季2019年6月-2019年8月

所有季节

1特惠活动2018年4月- 2018年4月

第八季2017年2月1日- 2017年3月

11第二季2018年4月-2018年6月

8第三季2019年6月-2019年8月

所有季节

其次,我可以通过遍历parent标记中的所有元素,一次隔离一个块,如下所示

1特惠活动2018年4月- 2018年4月

第三,我已经到了可以再次遍历并隔离位于徽章中的数字的阶段(我说徽章是因为它是如何在html代码中引用的)。

我还回溯并使用了阶段2,并在中放置了一个正则表达式函数来标识单词"specials“,但无法弄清楚如何跳过该单词并在running for循环中继续。

我认为我可能需要与父母,孩子,兄弟编码工作,以实现我想要的。

提前感谢

代码语言:javascript
复制
Sub()

Dim XML_05 As New MSXML2.XMLHTTP60
Dim HTML_05 As New MSHTML.HTMLDocument

XML_05.Open "GET", "https://www.thetvdb.com/series/legion", False
XML_05.send
HTML_05.body.innerHTML = XML_05.responseText

Dim NETC_05 As MSHTML.IHTMLElementCollection
Dim NET_05 As MSHTML.IHTMLElement
Dim REO_05 As VBScript_RegExp_55.RegExp
Dim MO_05 As Object
Dim SeasonsList As MSHTML.IHTMLElementCollection
Dim SeasonsInfo As MSHTML.IHTMLElement
Dim SI_05 As MSHTML.IHTMLElement
Dim Badge As MSHTML.IHTMLElement


Set SeasonsList = HTML_05.getElementsByClassName("hidden-sm hidden-md hidden-lg")

For Each SeasonsInfo In SeasonsList
    Debug.Print SeasonsList.Length
        For Each SI_05 In SeasonsInfo.getElementsByTagName("li")
                    For Each Badge In SI_05.Children
                    Debug.Print Badge.innerText
                Next Badge
        Next SI_05
Next SeasonsInfo

End Sub
EN

回答 1

Stack Overflow用户

发布于 2019-09-04 20:08:25

Specials是第一个,All Seasons是最后一个,所以您可以将nodeList1循环到nodeList.Length-2,以避免这两个节点,并简单地将两者之间的数字求和。我使用一个代理HTMLDocument变量来保存每个节点的querySelector,这样我就可以再次利用querySelector,并通过getElementsnextSibling等避免长链。我真的不确定在某个时候你是否也想要其他信息,所以我将每个季名、日期和剧集计数存储在一个数组results中(不包括所描述的节点)。这种方法还意味着将代码复杂度降低到单个循环。

代码语言:javascript
复制
Option Explicit
Public Sub GetTotalEpisodes()
    Dim i As Long, html As MSHTML.HTMLDocument, html2 As MSHTML.HTMLDocument, seasons As Object, results(), r As Long

    Set html = New HTMLDocument: Set html2 = New HTMLDocument

    With CreateObject("MSXML2.XMLHTTP")
        .Open "GET", "https://www.thetvdb.com/series/legion", False
        .send
        html.body.innerHTML = .responseText
    End With

    Set seasons = html.querySelectorAll(".hidden-xs .list-group-item")
    ReDim results(1 To seasons.Length - 2, 1 To 3)

    For i = 1 To seasons.Length - 2
        html2.body.innerHTML = seasons.item(i).outerHTML
        results(i, 1) = Trim$(html2.querySelector(".list-group-item-heading").innerText)
        results(i, 2) = Trim$(html2.querySelector(".list-group-item-text").innerText)
        results(i, 3) = 1 * html2.querySelector(".badge").innerText
    Next
    Debug.Print Application.Sum(Application.index(results, 0, 3))
End Sub

如果您希望存储包括第一个和最后一个节点在内的所有信息,但仍然执行条件求和,则可以在数组中包含要排除的标题,并在循环期间对其进行检查;仅当当前标题不在排除数组中时才求和

代码语言:javascript
复制
Option Explicit
Public Sub GetTotalEpisodes()
    Dim i As Long, html As MSHTML.HTMLDocument, html2 As MSHTML.HTMLDocument, seasons As Object, results(), r As Long
    Dim exclusions(), heading As String, badge As Long, total As Long

    Set html = New HTMLDocument: Set html2 = New HTMLDocument
    exclusions = Array("Specials", "All Seasons")
    With CreateObject("MSXML2.XMLHTTP")
        .Open "GET", "https://www.thetvdb.com/series/legion", False
        .send
        html.body.innerHTML = .responseText
    End With

    Set seasons = html.querySelectorAll(".hidden-xs .list-group-item")
    ReDim results(1 To seasons.Length, 1 To 3)

    On Error Resume Next
    For i = 0 To seasons.Length - 1
        html2.body.innerHTML = seasons.item(i).outerHTML
        heading = Trim$(html2.querySelector(".list-group-item-heading").innerText)
        badge = 1 * html2.querySelector(".badge").innerText
        results(i + 1, 1) = html2.querySelector(".list-group-item-heading").innerText
        results(i + 1, 2) = Trim$(html2.querySelector(".list-group-item-text").innerText)
        results(i + 1, 3) = badge
        If IsError(Application.match(heading, exclusions, 0)) Then
            total = total + badge
        End If
    Next
    On Error GoTo 0
    Debug.Print total
End Sub

操作问题:

  1. Option Explicit -强制变量declaration.

当Option Explicit On或Option Explicit出现在文件中时,必须使用

或ReDim语句显式声明所有变量。如果尝试使用未声明的变量名,则在编译时会发生错误。Option Explicit Off语句允许隐式声明变量。

这是最好的实践,也是捕捉打字错误的有用方法。

  1. results() -我声明了一个dynamic array,这意味着我还不知道所需的维度,但稍后会在知道时使用ReDim。它实际上是结果()作为变量(隐式地)。另请参见here。我可以稍后ReDim,因为在这一点上

Set .list-group-item") =html.querySelectorAll(“.hide-xs seasons

seasons.Length会给出results()的第一个维度的行数。

  1. querySelectorAll -类似于getElementsBy。它将一个css selector (或组合)应用于HTMLDocument (例如ie.Document)。

文档方法querySelectorAll()返回一个静态(非实时) NodeList,表示与指定选择器组匹配的文档元素列表

现代浏览器针对css进行了优化,因此这通常是一种快速而灵活的查找节点的方法。

  1. Trim$ -是Trim的类型化版本。它用于从node.innerText.
  2. The底部版本中删除多余的前导/尾随空格,该空格应适用于单个季节。只需更改数组exclusions以说明您希望包含/排除的内容。如果没有,请给我一个例子,我会为你更新。
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57787078

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档