2017-12-27 121 views
10

Tôi đã viết scraper theo vba để phân tích một số thông tin phim từ một trang web torrent. Tôi đã sử dụng IEqueryselector để hoàn thành tác vụ. Khi tôi thực thi mã của mình, nó phân tích cú pháp mọi thứ cùng với lỗi xuất hiện. Dường như lỗi xuất hiện từ hư không thay vì tiếp tục. Nếu tôi hủy bỏ hộp lỗi thì tôi có thể thấy kết quả. Tôi đã tải lên hai hình ảnh dưới đây để hiển thị cho bạn các lỗi tôi đang gặp phải. Làm cách nào tôi có thể thực thi mã thành công mà không gặp bất kỳ lỗi nào? Cảm ơn trước.Trình gỡ rối của tôi ném lỗi thay vì thoát trình duyệt khi mọi thứ được thực hiện

Đây là mã đầy đủ:

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 

Các lỗi Tôi đang gặp:

First error

Second error

Cả hai lỗi được xuất hiện cùng một lúc. Tôi đang sử dụng Internet Explorer 11.

Mặt khác, Nếu tôi cố gắng như dưới đây, nó sẽ mang lại kết quả thành công mà không gặp vấn đề gì.

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 

tham khảo tôi đã thêm vào thư viện:

1. Microsoft Internet Controls 
2. Microsoft HTML Object Library 

Vì vậy, những gì là sai với queryselector hoặc những gì tôi đang mất tích ở đây để tạo ra một đi thành công? Có bất kỳ tham chiếu nào để thêm vào thư viện để xóa các lỗi không?

+0

Kiểm tra nhanh: thay đổi 'queryselector' thành' querySelector' có tạo sự khác biệt nào trong mẫu mã đầu tiên không? – alecxe

+0

Không, thưa ông. Trong thực tế, nếu tôi cố gắng viết 'querySelector', nó sẽ tự động quay trở lại chữ thường, đó là' queryselector'. – SIM

+0

Được rồi, hãy thử điều này: thay vì thực hiện 'post.queryselector' chỉ cần thực hiện trực tiếp' post.innerText'. Nó không phải là những gì bạn muốn làm nhưng chúng ta hãy thử nghiệm. Bạn có thấy lỗi giống nhau không? Cảm ơn. – alecxe

Trả lời

5

Ok, do đó, có điều gì đó nghiêm trọng không thân thiện với trang web đó. Nó cứ đâm vào tôi. Vì vậy, tôi đã sử dụng để chạy một chương trình javascript trong kịch bản động cơ/scripting kiểm soát và nó hoạt động.

Tôi hy vọng bạn có thể theo dõi nó. Logic là trong javascript được thêm vào ScriptEngine. Tôi nhận được hai danh sách các nút, một danh sách các bộ phim và một danh sách các năm; sau đó tôi duyệt qua từng mảng đồng bộ và thêm chúng dưới dạng cặp giá trị khóa vào một Từ điển Microsoft Scripting.

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

Vâng, có vẻ như tôi đã tìm thấy giải pháp để làm việc với .queryselectorAll(). Sau khi thử nghiệm rất nhiều, tôi có thể nhận thấy rằng nó chỉ có một số vấn đề với for loop vì vậy tôi khéo léo tránh for loop và sử dụng with block thay vào đó để làm cùng một công việc. Đây là cách chúng ta có thể đạt được điều đó:

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, kịch bản trên có thể được thực hiện mà không tham khảo bất cứ điều gì đến thư viện.

Các vấn đề liên quan