Vấn đề HttpRequest “Get” trả về Response khác với Reponse thao tác trên trình duyệt

Chia sẻ bởi:hands
★★★★★
Quảng cáo

Chào các bạn,
Tôi gặp một vấn đề là khi dùng Http request – GET thì nó trả về cái Response nhưng kiểm tra lại thì khác với Response tôi thao tác trực tiếp trên trang web.
– Tìm theo MST, CCCD dùng "masothue.com/Ajax/Search/" thì chạy rất nhanh nhưng khi tìm bằng tên thì không chạy.
– Tôi dùng "masothue.com/Search/?q" & chuỗi tên thì lại trả về Response sai. Đã thử khai báo các header đúng như trên trình duyệt cũng không sửa được lỗi.

File đính kèm bên dưới. Nhờ các bạn hướng dẫn tìm ra nguyên nhân của vấn đề trên.
Cảm ơn.

Dim js As Object
    Set js = CreateObject("Scripting.Dictionary")

Dim formData As String, sTenCty As String, res As String
    Const url As String = "masothue.com/Search/"

res = httpPost("masothue.com/Ajax/Token", "")
    Set js = JsonConverter.ParseJSON(res)

sTenCty = UCase(Sheet1.Range("A1"))
    formData = "?q=" & URLEncode(CStr(sTenCty), True) & "&type=enterpriseName&token=" & js("token") & "&force-search=1"
    Debug.Print url & formData

res = httpGet(url & formData)
    Debug.Print res
Function httpGet$(url$)
    'With CreateObject("WinHttp.WinHttpRequest.5.1")
    With CreateObject("MSXML2.serverXMLHTTP.6.0")
        .Open "GET", url, False
        .setRequestHeader "User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36 Edg/90.0.818.51"
        .setRequestHeader "Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"
        .send
        httpGet = .responseText

Dim getStatus As String
        If Err.Number <> 0 Then
            'khong co phan hoi tu server
        Else
            getStatus = .Status
            If getStatus <> "300" And getStatus <> "200" Then
                Debug.Print "Some problems raised."
            Else
                Debug.Print "Connected."
            End If
        End If

On Error GoTo 0
    End With
End Function

Với Request Headers thì anh quan tâm chủ yếu cái:
"Content-Type"
"Cookie"

Cái cookie thì xử lý như thế nào befaint. Anh lấy luôn cái cookie trong Request Header của trình duyệt gán vô hàm nhưng cũng không sửa lỗi được.

2281

hế sao được anh. 🙂

Cái cookie đó chứa Session ID của client khi kết nối server. Anh kết nối trình duyệt và dùng code là 2 phiên làm việc khác nhau, nên Session ID khác nhau rồi.
Anh có code Python thử được không? Mấy cái này bên Python có Session của Request nó giữ phiên làm việc luôn, và lấy cookie rất dễ.

Cách lấy cookie: Anh kết nối trang chủ, tạo kết nối đầu tiên tới server, nó sinh ra 1 cookie, anh tìm mọi ngóc ngách xem nằm ở đâu, lấy cái đó gán cho headers.
2282

Anh thử tìm hiểu phần mềm Postman ấy. Công cụ bắt gói tin, giúp mình tìm API, các thông số cần thiết. Hoặc trên trình duyệt có nhiều Addons như HTTP header live…

Anh lấy cái PHPSESSID từ Chrome như hình thêm vô Header mà cũng không ra đúng yêu cầu. Về web thì anh không biết nó cho lắm, không biết sai công đoạn nào.
Mỗi lần POST hay GET là nó tạo một "Cookie: PHPSESSID" mới. Anh lấy cái Cookie từ POST gắn vô GET cũng không ra ResponseText đúng. Không biết xử lý vụ này ra sao.

2283

.setRequestHeader "cookie", "PHPSESSID=a3q7cpkp95ebh4f43fiqqj64q7"

Mình không biết xài cookie lấy đoạn code trên mạng về chạy thử tự nhiên ra kết quả, hay máy mình bị virus nhỉ

Sub hello()
Dim sResponse As String, Url As String, objHTTP

Set objHTTP = CreateObject("WinHttp.WinHttpRequest.5.1")
Url = "masothue.com/Ajax/Search"
objHTTP.Open "POST", Url, False
objHTTP.setRequestHeader "User-Agent", "ahihi"
objHTTP.setRequestHeader "Content-type", "application/x-www-form-urlencoded"
objHTTP.send ("q=0304408986&type=auto&force-search=1")
sResponse = objHTTP.responseText
MsgBox sResponse
End Sub

www.giaiphapexcel.com/diendan/threads/v%E1%BA%A5n-%C4%91%E1%BB%81-httprequest-get-tr%E1%BA%A3-v%E1%BB%81-response-kh%C3%A1c-v%E1%BB%9Bi-reponse-thao-t%C3%A1c-tr%C3%AAn-tr%C3%ACnh-duy%E1%BB%87t.155487/

Ứng dụng AI và Chat GPT trong Quản trị nhân sự
Khóa học SprinGO phù hợp

Ứng dụng AI và Chat GPT trong Quản trị nhân sự

Học xong khóa này, học viên có thể: Hiểu đúng bản chất AI, các nhóm AI phổ biến và cách AI “hoạt động” ở...

Xem khóa học
★★★★★ 5 ★ 1 👤 6 ▥ 0
Quảng cáo

Bạn nên đọc

6 Responses

  1. hands says:

    Thớt có biết với tìm theo tên thì ra mấy trường hợp ? và ứng với từng trường hợp cần làm gì chưa ? Hãy nói thêm để làm rõ vấn đề

    Nếu response đúng như web trả về thì tôi chỉ cần liệt kê tên cty để người dùng tự chọn tên cty mình cần truy vấn tiếp. Các bước xử ly HTMLDocument hoặc chuỗi Json thì tôi xử lý được bạn.

    Ở trên tôi có hỏi là tìm theo tên thì ra mấy trường hợp ? Bạn không muốn trả lời thì thôi, tôi hỏi vì ứng với từng trường hợp thì code sẽ khác, và cũng không dễ, có trả lời thì con đường đi ngắn hơn.
    Vậy tôi có đoạn code tìm kiếm theo tên công ty, bạn ghi lại Response chép vào file text rồi tự phân tích kết quả cần lấy nhé.

    Sub hello()
    Dim sResponse As String, Url As String, objHTTP
    
    Set objHTTP = CreateObject("WinHttp.WinHttpRequest.5.1")
    Url = "masothue.com/Search/?q=C%C3%B4ng+ty+Vi%E1%BB%87t+H%C3%A0&type=auto&force-search=1"
    objHTTP.Open "GET", Url, False
    objHTTP.setRequestHeader "User-Agent", "ahihi"
    objHTTP.send
    sResponse = objHTTP.responseText
    End Sub

    Ôi trời…đọc code của bạn xong tôi mới thấy mình mắc một cái lỗi ngớ ngẩn nhưng trả giá bằng thời gian là: Kiểm tra kết quả sai cách. Tôi làm biếng, không thêm code ghi ResponseText ra file Text mà chỉ Debug.Print vào cửa số Immediate mà cửa sổ này hiển thị có giới hạn số lượng ký tự. Tượng tự ghi xuống Cell Excel cũng bị giới hạn ký tự –> Copy ra Notepad++ thấy thiếu quá trời dòng (tổng ~ 900 dòng – 76.320 ký tự). :wallbash:
    Nói chung code trong file bài đầu của tôi ra kết quả đúng mà phương pháp kiểm của tôi sai quá sai nên làm phiền mọi người.

    Còn vụ bạn hỏi ở trên thì chắc do tôi không hiểu rõ trong câu hỏi. Response trả về khi tìm theo từ khoá tên sẽ liệt kê ra nhiều cty có tên trùng từ khoá. Từ đó tôi mới đọc file HTML này để lấy toàn bộ tên Cty trong đây (đường link, MST…) ghi xuống Listbox để người dùng tự chọn -> lập lại bước truy vấn theo MST hoặc theo URL tên Cty.
    Đây là trả lời của tôi theo cách tôi hiểu câu "Tìm theo tên thì ra mấy trường hợp?" của bạn.

    Cảm ơn bạn đã quan tâm trả lời.

    (Cập nhật file chạy không lỗi.)

  2. hands says:

    Sao em nhập thử mã số thuế vào ô tìm kiếm mà không ra kết quả nhỉ?
    22872286

    Hay Code chưa hiểu tìm theo kiểu text/number? Search trên web thì có ra kết quả.
    Cảm ơn anh.

    Em đổi dòng URL:
    formData = "?q=" & URLEncode(CStr(sTenCty), True) & "&type=enterpriseName&force-search=1"

    Thành
    formData = "?q=" & URLEncode(CStr(sTenCty), True) & "&type=enterpriseTax&force-search=1"

    Trong chương trình nên tạo tùy chọn kiểu tiemf kiếm, ứng vói mỗi kiểm tìm mà thay thế tham số "type" trong URL tương ứng.

    Danh sách các tham số của TYPE:
    Mẫu lệnh:
    formData = "?q=" & URLEncode(CStr(sTenCty), True) & "&type=TypeValue&force-search=1"
    TypeValue là các giá trị:
    + enterpriseName : nếu tìm tên công ty
    + enterpriseTax : nếu tìm MST
    + identity : tìm CMND/CCCD
    + legalName : tìm tên giám đốc
    + auto : tự tìm theo đặc điểm giá trị tìm (thường chính xác với MST và tên cty)

    Trong chương trình nên tạo tùy chọn kiểu tiemf kiếm, ứng vói mỗi kiểm tìm mà thay thế tham số "type" trong URL tương ứng.

    Em có đổi sang enterpriseTax, thì lại ra kết quả không liên quan gì luôn anh ạ.
    2288

    File này tôi chỉ làm tìm kiếm theo Tên Cty thôi chứ không tìm theo MST.
    Trước đây code này có thể tìm theo MST được nhưng sau này trang masothue.vn nó thay đổi, chuỗi Json trả về không còn kèm theo cái link trực tiếp tới đích danh MST Cty nữa nên kết quả trả về chạy lung tung.

    264996

    Tôi hiện thời chưa biết cách xử lý, chỉ xử lý được là tìm theo tên rồi mới tìm tiếp theo MST vừa trả về thôi.
    File này tôi chỉ làm tìm kiếm theo Tên Cty thôi chứ không tìm theo MST.
    Trước đây code này có thể tìm theo MST được nhưng sau này trang masothue.vn nó thay đổi, chuỗi Json trả về không còn kèm theo cái link trực tiếp tới đích danh MST Cty nữa nên kết quả trả về chạy lung tung.

    2290

    Tôi hiện thời chưa biết cách xử lý, chỉ xử lý được là tìm theo tên rồi mới tìm tiếp theo MST vừa trả về thôi.
    File sửa đính kèm bên dưới.

    File sửa đính kèm bên dưới.

    Vâng, cảm ơn anh.
    Kể ra có các option tùy chọn tìm kiếm như anh @Nguyễn Duy Tuân nói thì tuyệt.
    Rất mong các thành viên cùng xây dựng và hoàn thiên, để có một công cụ hữu ích cho cộng đồng.

    Trang mã số thuế này lúc trước nó chỉ chặn IP khi số lần khi request quá nhiều trong một khoảng thời gian nào đó khoảng 200-300 lần gì đó, khi đó tôi cần kiểm tra một số lượng MST lớn nên đã fake ID làm cho cái lượng request trong ngày lên tới 100.000 có thể sau đó nó phát hiện nên đã đổi lại cách thức, nó dùng một cái token kèm theo như hình bạn chụp cùng đi kèm cái phiên hiện tại và cái khó nữa là cái token đó sẽ chết sau một thời gian nên phải làm mới lại token, nên việc get một số lượng lớn thông tin bây giờ sẽ khó hơn chút, còn nếu get vài lần thì thêm bước get token nữa là giống y cũ thôi bạn
    2291

    Cảm ơn bạn.
    Tôi cũng đã sửa lại nhưng không biết còn sai chỗ khai báo nào mà chuỗi Json trả về cũng chưa đúng như của bạn. Bạn kiểm tra giùm tôi nhé.

    res = httpPost("masothue.com/Ajax/Token", "")
        'Debug.Print res
        Set js = JsonConverter.ParseJSON(res)
    
    sMST = "0304440926"
        formData = "?q=" & sMST & "&type=auto&token=" & js("token") & "&force-search=1"
        'Debug.Print formData
    
    res = httpPost("masothue.com/Ajax/Search", formData)
    
    Debug.Print "----------------------------------------" & vbCrLf
        Debug.Print res

    2293

    Nên viết trong một object request để cùng phiên bạn, code bạn gọi hàm httpPost 2 lần tức là đang tạo 2 phiên khác nhau rồi, đồng thời sửa formData = "?q=" thành formData = "q="
    2294

    Cái mấu chốt nó nằm ở đây :thumbs:. Bữa giờ cứ loay hoay không biết nguyên nhân, không xử lý được đoạn này.
    Cảm ơn bạn nhé.

  3. hands says:

    Tôi đã hoàn thiện thêm code của file gửi trên trang đầu như sau:
    1. Thiết lập khai báo tìm tùy ý các thông tin
    2. Cho phép tìm MST chính xác, web thấy sao Excel thấy vậy.

    2295

    Mã nguồn (có một số đoạn code file cũ thừa tôi không xóa, để đó để các bạn ứng dụng cho vieeucj khác):

    Sub LayTenDN()
    
    'On Error GoTo ErrorHandler
        Dim js As Object, res As String, TypeValue As String
        Set js = CreateObject("Scripting.Dictionary")
    
    Dim formData As String, sTenCty As String ', res As String
        Const Url As String = "masothue.com/Search/"
    
    res = httpPost("masothue.com/Ajax/Token", "")
        Set js = JsonConverter.ParseJSON(res)
    
    TypeValue = Range("TypeValue").Value
    
    sTenCty = UCase(Sheet1.Range("B3"))
        formData = "?q=" & URLEncode(CStr(sTenCty), True) & _
                    "&type=" & TypeValue & _
                    "&force-search=1"
    
    res = httpGet(Url & formData)
        Call Write2Sheet(res, TypeValue)
    
    ErrorHandler_Exit:
        Exit Sub
    
    ErrorHandler:
        MsgBox "Có lõi phát sinh." & vbCrLf & "Mã loi: " & Err.Number & vbCrLf & "Noi dung loi: " & Err.Description, vbExclamation, "Thông báo"
        Resume ErrorHandler_Exit
    
    End Sub
    
    Sub Write2Sheet(ByVal sHTML As String, ByVal TypeValue As String)
        Dim oHtml As HTMLDocument
        Dim oElement As Object, prc As Object, prc2 As Object
        Dim i As Long, j As Long, k As Long
    
    On Error GoTo lbEndSub
    
    Set oHtml = New HTMLDocument
        oHtml.body.innerHTML = sHTML
        Sheet1.Range("A7:D1000").ClearContents
        Sheet1.Range("D3") = "Xin cho..."
    
    If TypeValue = "enterpriseTax" Then
            'table-taxinfo
            Dim tb As Object, row As Object, r As Long
            'Set tb = oHtml.getElementsByClassName("Table - taxinfo")
            Set tb = oHtml.getElementsByTagName("TABLE")(0)
            For r = 0 To tb.Rows.Length - 1
                Set row = tb.Rows(r)
                Cells(r + 7, 1).Value = row.Cells(0).innerText
                If row.Cells.Length > 1 Then
                    Cells(r + 7, 2).Value = row.Cells(1).innerText
                End If
            Next
            GoTo lbEndSub
        End If
    
    Set prc = oHtml.getElementsByClassName("tax-listing")(0).getElementsByTagName("a")
        Set prc2 = oHtml.getElementsByClassName("tax-listing")(0).getElementsByTagName("address")
    
    i = 0: j = 0: k = 0
        For Each oElement In prc
            If k > 2 Then
                k = 0: j = j + 1
            End If
            Sheet1.Range("A7").Offset(j, k) = prc(i).innerText
            Sheet1.Range("D7").Offset(j, 0) = prc2(j).innerText
            i = i + 1: k = k + 1
        Next oElement
    
    lbEndSub:
        If Err <> 0 Then
            Sheet1.Range("D3") = "Loi tim kiem? Hay kiem tr kieu tim kiem."
            Sheet1.Range("D3").Font.Color = vbRed
        Else
            Sheet1.Range("D3") = "Xong."
            Sheet1.Range("D3").Font.Color = vbGreen
        End If
        Set oHtml = Nothing
        Set oElement = Nothing
    
    End Sub

    Mã nguồn (có một số đoạn code file cũ thừa tôi không xóa, để đó để các bạn ứng dụng cho vieeucj khác)

  4. hands says:

    Mình mới kiểm tra lại File lấy thông tin chỗ a Tuân ở máy nơi khác (khác IP máy mình) thì chạy bình thường. Tuy nhiên cái mình đang làm là tra cứu mã số thuế TNCN từ số CMND(hoặc căn cước)
    Code mình như sau (hôm qua chạy ngon lành, sáng nay thì lỗi, không chạy được nữa )
    Mình qua 2 lần Post và Get, nếu 1 lần Post và 1 lần Get thì nếu số CMND đó mình mới tra cứu thì nó ra kết quả còn nếu số CMND đó chưa tra cứu thì nó không ra kết quả, chả biết nguyên nhân tại sao !

    Function LayTTMSTNCN(ByVal SoCMND As String)
    Dim Msg As String, Url As String
    Dim hreq As Object, html As Object, js As Object
    
    Set hreq = CreateObject("WinHttp.WinHttpRequest.5.1")
        Set html = CreateObject("htmlfile")
        Set js = CreateObject("Scripting.Dictionary")
    
    With hreq
            .Open "POST", "masothue.com/Ajax/Token", False
            .setRequestHeader "User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36"
            .setRequestHeader "Content-type", "application/x-www-form-urlencoded; charset=UTF-8"
            .send (Msg)
            Set js = JsonConverter.ParseJSON(.responseText)
    
    Msg = "q=" & SoCMND & "&type=personalTax&token=" & js("token") & "&force-search=1"
            .Open "POST", "masothue.com/Ajax/Search", False
            .setRequestHeader "User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36"
            .setRequestHeader "Content-type", "application/x-www-form-urlencoded; charset=UTF-8"
            .send (Msg)
            .WaitForResponse
    
    Url = GetUrl(.responseText)
            If InStr(1, Url, "chu01b0a cu00f3") > 0 Or Len(Url) = 0 Then
                LayTTMSTNCN = "Chua cap MST"
                Exit Function
            Else
                .Open "GET", "masothue.com" & Url, False
                .send
                html.body.innerHTML = .responseText
    
    If Err.Number Then
                    Err.Clear
                Else
                    LayTTMSTNCN = html.getElementsByClassName("table-taxinfo")(0).innerText
                End If
                html.Close
            End If
        End With
    
    Set hreq = Nothing
        Set html = Nothing
        Set js = Nothing
    
    End Function
    
    Function GetUrl(ByVal str As String)
        Dim h As Long, i As Long, s As String
        h = InStr(1, str, "/")
        If h > 0 Then
            For i = h + 2 To Len(str)
                If Mid(str, i, 1) = Chr(34) Then
                    s = Mid(str, h + 1, i - h - 1)
                    Exit For
                End If
            Next i
            GetUrl = s
        End If
    End Function

    Tắt modem router, khởi động lại là được.

    Mới sửa lại cái file tra cứu theo các kiểu: MST , CCCD (CMND), Tên DN và thêm cái tìm theo danh sách MST vì lúc trước có bạn hỏi.

    2298

  5. hands says:

    2299

    Làm như nào bây giờ để nó có thể chạy mượt mà được bây giờ?

    sáng còn Fake IP được, chiều nó khóa luôn rồi !

    Họ dùng công nghệ gì không biết mà có thể khóa được nhỉ?

    Một cách sửa lỗi trên là không dùng WinHTTP mà đổi sang MSXML2. Trong code tôi có viết sẳn rồi.

    2302

    Nếu dùng WinHTTP thì bạn chạy file đính kèm xem sửa lỗi TLS của Windows xem còn lỗi không. Do máy tôi cài rồi nên chạy không lỗi.
    Theo tôi biết thì nguyên nhân nó tương tự như nội dung bên dưới:

    2301

    Và link down ở đây: docs.microsoft.com/en-us/answers/questions/247500/tls-11-and-tls-12-easy-fix-download-missing.html

    Còn về vụ khoá IP thì tôi không rành web nên nghĩ chắc họ dùng các tool để chống DDOS hoặc kỹ thuậnt anti-scraping gì đó.

    Tôi nghĩ bạn viết đoạn code fake cái proxy của nó để hoàn chỉnh, proxy thì lấy mấy cái proxy free ở web nó làm mới thường xuyên nên có chết hay bị chặn cũng chẳng sao, lấy trong web này http://www.sslproxies.org/ lấy mấy thằng port 8080 thôi để hạn chế mấy cái proxy không hoạt động
    2303

    đã thành công, tuy nhiên tốc độ request khá chậm, Mình có thể dùng IP gì hoặc ở nước nào cho tốc độ nhanh hơn được không bạn ?

    Bạn bỏ cái header này đi xem còn chạy được không?

    2307

    mình bỏ đoạn này vẫn không chạy được bạn !
    Cảm ơn bạn !

  6. hands says:

    Do phần mềm xuất hóa đơn Invoice mình đang dùng không có chức năng "Lấy thông tin" từ web (như Misa hóa đơn click vào nút "Lấy thông tin" sẽ tự động tra cứu theo dữ liệu trên web thuế). Hiện tại "Danh sách khách hàng" trên phần mềm khi địa chỉ thay đổi sẽ không cập nhật lại, rất tốn thời gian kiểm tra lại và khi lỡ xuất hóa đơn rồi bên mua lại yêu cầu làm biên bản điều chỉnh hóa đơn nếu thông tin khách hàng thay đổi.
    Mình xin mượn code và file của anh Tuân để tra cứu mã số thuế. Mình chỉnh sửa lại code ghi dữ liệu theo cột (module TestMST_Column) mục đích để tra cứu được nhiều mã số thuế. Tuy nhiên mình thấy nhiều bài mấy bạn nói IP bị chặn nếu "sent" và "get" lên web nhiều quá, danh sách mình có khoản 200 mã số thuế cần dò lại, không biết nếu click tra cứu lấy một lúc 200 mã số thuế thì có bị chặn IP không, mình sợ bị chặn IP nên có để code cách 2s gửi lệnh 1 lần:

    Application.Wait Now + TimeValue("00:00:2")

    Mong anh chị xem giúp đỡ và tư vấn thêm giúp mình.

    Bạn xem file demo bài trên.

    File của bạn hay quá, làm mình mò code cả tuần nay. Cám ơn bạn rất nhiều, giờ thì kiểm tra danh sách MST tiện lợi và nhanh chóng rồi.
    Bạn ơi cho mình hỏi "Tra cứu theo danh sách" nếu MST chi nhánh (có thêm đuôi -001) thì kết quả chỉ trả về thông tin cty mẹ thôi hả bạn. Có cách nào hiện thông tin địa chỉ của chi nhánh không bạn.

    Nó vẫn ra thông tin chi nhánh mà bạn.

    Ví dụ MST như trong hình này nè bạn: 2 địa chỉ khác nhau, nếu MST chi nhánh thì địa chỉ như trong hình bên phải.
    2306
    Cho mình hỏi thêm khi click Tra cứu chi tiết thì báo lỗi tại dòng này:
    2305

    – Tôi có ghi chú đầu bài là lấy thông tin từ trang masothue.vn. Do đó nếu trang đó chưa cập nhật thì cũng bó tay.
    – Nút tra cứu chi tiết là dùng khi bạn tìm theo tên DN nhập ở ô bên trái –> nó sẽ trả về một danh sách các cty có tên giống vậy và bạn click chọn MST của Cty nào cần xem chi tiết.

Leave a Reply

Your email address will not be published. Required fields are marked *

Quảng cáo

Cũ vẫn chất

Xem thêm