2017-12-27 86 views
10

मैंने एक टोरेंट साइट से कुछ फिल्म जानकारी पार्स करने के लिए vba में एक स्क्रैपर लिखा है। मैंने कार्य को पूरा करने के लिए IE और queryselector का उपयोग किया। जब मैं अपना कोड निष्पादित करता हूं तो यह एक त्रुटि पॉप-अप के साथ सब कुछ पार्स करता है। ऐसा लगता है कि त्रुटि जारी रखने के बजाय कहीं भी नहीं दिखाई देती है। अगर मैं त्रुटि बॉक्स को रद्द करता हूं तो मैं परिणाम देख सकता हूं। मैंने आपको त्रुटियों को दिखाने के लिए नीचे दो छवियां अपलोड की हैं। बिना किसी त्रुटि के कोड सफलतापूर्वक निष्पादित कैसे कर सकता हूं? अग्रिम में धन्यवाद।सब कुछ किया जाता है जब ब्राउज़र को छोड़ने के बजाए मेरा स्क्रैपर त्रुटियों को फेंक देता है

Sub Torrent_Data() 
    Dim IE As New InternetExplorer, html As HTMLDocument 
    Dim post As Object 

    With IE 
     .Visible = False 
     .navigate "https://yts.am/browse-movies" 
     Do While .readyState <> READYSTATE_COMPLETE: Loop 
     Set html = .Document 
    End With 

    For Each post In html.querySelectorAll(".browse-movie-bottom") 
     Row = Row + 1: Cells(Row, 1) = post.queryselector(".browse-movie-title").innerText 
     Cells(Row, 2) = post.queryselector(".browse-movie-year").innerText 
    Next post 
    IE.Quit 
End Sub 

त्रुटियों मैं आ रही हैं:

First error

Second error

त्रुटियों की

दोनों एक ही समय में दिखाई दे रहे हैं

यहाँ पूर्ण कोड है। मैं इंटरनेट एक्सप्लोरर 11.

दूसरी तरफ, यदि मैं नीचे की कोशिश करता हूं तो यह परिणाम बिना किसी समस्या के सफलतापूर्वक लाता है।

Sub Torrent_Data() 
    Dim IE As New InternetExplorer, html As HTMLDocument 
    Dim post As Object 

    With IE 
     .Visible = False 
     .navigate "https://yts.am/browse-movies" 
     Do While .readyState <> READYSTATE_COMPLETE: Loop 
     Set html = .Document 
    End With 

    For Each post In html.getElementsByClassName("browse-movie-bottom") 
     Row = Row + 1: Cells(Row, 1) = post.queryselector(".browse-movie-title").innerText 
     Cells(Row, 2) = post.queryselector(".browse-movie-year").innerText 
    Next post 
    IE.Quit 
End Sub 

संदर्भ मैं पुस्तकालय के लिए जोड़ दिया है:

1. Microsoft Internet Controls 
2. Microsoft HTML Object Library 

तो, क्या queryselector साथ कुछ गड़बड़ है या क्या मैं यहाँ याद कर रहा हूँ एक सफलतापूर्वक जाना बनाने के लिए? क्या त्रुटियों को हिलाकर पुस्तकालय में जोड़ने का कोई संदर्भ है?

+0

त्वरित जांच: 'queryselector' को 'क्वेरी चयनकर्ता' में बदलकर पहले कोड नमूने में कोई अंतर आता है? – alecxe

+0

नोप सर, बिल्कुल कोई बदलाव नहीं। वास्तव में, अगर मैं 'क्वेरी चयनकर्ता' लिखने का प्रयास करता हूं, तो यह स्वचालित रूप से लोअरकेस पर वापस आता है जो 'queryselector' है। – SIM

+0

ठीक है, इसे आज़माएं: 'post.queryselector' को निष्पादित करने के बजाय बस 'post.innerText' को सीधे करें। यह वह नहीं है जिसे आप करना चाहते थे लेकिन चलो प्रयोग करें। क्या आप एक ही त्रुटि देखते हैं? धन्यवाद। – alecxe

उत्तर

5

ठीक है, तो उस वेबपृष्ठ के बारे में कुछ गंभीरता से असभ्य है। यह मेरे लिए दुर्घटनाग्रस्त रहा। तो मैंने स्क्रिप्टिंग इंजन/स्क्रिप्टिंग नियंत्रण के भीतर एक जावास्क्रिप्ट प्रोग्राम चलाने का सहारा लिया है और यह काम करता है।

मुझे आशा है कि आप इसका अनुसरण कर सकते हैं। तर्क स्क्रिप्टइंजिन में जोड़े गए जावास्क्रिप्ट में है। मुझे नोड्स की दो सूचियां, फिल्मों की एक सूची और वर्षों की एक सूची मिलती है; तो मैं सिंक में प्रत्येक सरणी के माध्यम से कदम उठाता हूं और उन्हें माइक्रोसॉफ्ट स्क्रिप्टिंग डिक्शनरी में महत्वपूर्ण मूल्य जोड़ी के रूप में जोड़ता हूं।

Option Explicit 

'*Tools->References 
'* Microsoft Scripting Runtime 
'* Microsoft Scripting Control 
'* Microsoft Internet Controls 
'* Microsoft HTML Object Library 

Sub Torrent_Data() 
    Dim row As Long 
    Dim IE As New InternetExplorer, html As HTMLDocument 
    Dim post As Object 

    With IE 
     .Visible = True 
     .navigate "https://yts.am/browse-movies" 
     Do While .readyState <> READYSTATE_COMPLETE: 
      DoEvents 
     Loop 
     Set html = .document 
    End With 

    Dim dicFilms As Scripting.Dictionary 
    Set dicFilms = New Scripting.Dictionary 

    Call GetScriptEngine.Run("getMovies", html, dicFilms) 

    Dim vFilms As Variant 
    vFilms = dicFilms.Keys 

    Dim vYears As Variant 
    vYears = dicFilms.Items 

    Dim lRowLoop As Long 
    For lRowLoop = 0 To dicFilms.Count - 1 

     Cells(lRowLoop + 1, 1) = vFilms(lRowLoop) 
     Cells(lRowLoop + 1, 2) = vYears(lRowLoop) 

    Next lRowLoop 

    Stop 

    IE.Quit 
End Sub 

Private Function GetScriptEngine() As ScriptControl 
    '* see code from this SO Q & A 
    ' https://stackoverflow.com/questions/37711073/in-excel-vba-on-windows-how-to-get-stringified-json-respresentation-instead-of 
    Static soScriptEngine As ScriptControl 
    If soScriptEngine Is Nothing Then 
     Set soScriptEngine = New ScriptControl 
     soScriptEngine.Language = "JScript" 

     soScriptEngine.AddCode "function getMovies(htmlDocument, microsoftDict) { " & _ 
            "var titles = htmlDocument.querySelectorAll('a.browse-movie-title'), i;" & _ 
            "var years = htmlDocument.querySelectorAll('div.browse-movie-year'), j;" & _ 
            "if (years.length === years.length) {" & _ 
            "for (i=0; i< years.length; ++i) {" & _ 
            " var film = titles[i].innerText;" & _ 
            " var year = years[i].innerText;" & _ 
            " microsoftDict.Add(film, year);" & _ 
            "}}}" 

    End If 
    Set GetScriptEngine = soScriptEngine 
End Function 
0

खैर, यह मैं .queryselectorAll() के साथ काम करने के लिए एक समाधान मिल गया है लगता है। बहुत प्रयोग करने के बाद मैं देख सकता था कि इसमें केवल for loop के साथ कुछ समस्याएं हैं इसलिए मैंने for loop से कुशलतापूर्वक टाला और with block का उपयोग उसी काम करने के बजाय किया।

Sub Torrent_Data() 

    With CreateObject("InternetExplorer.Application") 
     .Visible = False 
     .navigate "https://yts.am/browse-movies" 
     While .Busy = True Or .readyState < 4: DoEvents: Wend 

     With .document.querySelectorAll(".browse-movie-bottom") 
      For I = 0 To .Length - 1 
       Cells(I + 1, 1) = .Item(I).querySelector(".browse-movie-title").innerText 
       Cells(I + 1, 2) = .Item(I).querySelector(".browse-movie-year").innerText 
      Next I 
     End With 
    End With 

End Sub 

Btw, ऊपर स्क्रिप्ट पुस्तकालय के लिए कुछ भी संदर्भ के बिना क्रियान्वित किया जा सकता: यहाँ हम चाहते हैं कि कैसे प्राप्त कर सकते हैं।

संबंधित मुद्दे

 संबंधित मुद्दे