使用 WinInet (C++) 提交表单数据

问题描述 投票:0回答:1

我是一名专业律师和业余程序员(主要是C++)。每天,我必须访问同一个网站并搜索大量法庭案件(纯文本)。最近,我想到了编写一个简单的C++函数来自动将表单数据提交到网站的想法,这将节省我大量的工作时间。过去几天我一直在学习 WinInet,经过几个小时后,我成功发送了一个简单的 GET 请求并检索了主页源代码,但我无法再进一步了。我的目标是向网站发送带有搜索参数的 POST 请求(我认为),并获取真实搜索结果页面的源代码作为响应。

到目前为止我编写的程序几乎毫无价值,但至少它让我了解了我当前的状态。

#include <windows.h>
#include <wininet.h>
#include <string>

#pragma comment (lib, "Wininet.lib")

bool GetRequest() {

    HINTERNET hSession = InternetOpen(L"Mozilla/5.0", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
    if (!hSession) return false;

    HINTERNET hConnect = InternetConnect(hSession, L"scon.stj.jus.br", INTERNET_INVALID_PORT_NUMBER, L"", L"", INTERNET_SERVICE_HTTP, 0, 0);
    if (!hConnect) return false;

    HINTERNET hRequest = HttpOpenRequest(hConnect, L"GET", L"/", NULL, NULL, NULL, INTERNET_FLAG_KEEP_CONNECTION, 0);
    if (!hRequest) return false;

    if (!HttpSendRequest(hRequest, 0, 0, 0, 0)) return false;

    //from here on, I am able to read the main page source code using InternetReadFile, but I can't submit any form data

    InternetCloseHandle(hRequest);
    InternetCloseHandle(hConnect);
    InternetCloseHandle(hSession);

    return true;

}
c++ post wininet
1个回答
0
投票

如果您查看相关页面的 HTML,您会发现它有多个

<form>
元素,例如:

<form id="frmPesquisaJurHeader" name="frmPesquisaJurHeader"
                                    action="https://scon.stj.jus.br/SCON/pesquisar.jsp" method="post" target="_blank"
                                    style="display: none">
                                    <input name="b" value="ACOR" type="hidden">
                                    <input name="O" value="JT" type="hidden">
                                    <input name="livre" id="headerLivre" type="hidden" value="">
                                </form>

您可以看到此网络表单需要向

POST
发出
https://scon.stj.jus.br/SCON/pesquisar.jsp
请求,并包含 3 个
<input>
值。

由于

enctype
元素上没有
<form>
属性,因此请求的媒体类型预计为
application/x-www-form-urlencoded
,它采用由
name=value
分隔的
&
对。

因此,这样的网络表单将像这样提交:

#include <windows.h>
#include <wininet.h>
#include <string>

#pragma comment (lib, "Wininet.lib")

bool GetRequest() {

    std::string queryValues = "b=ACOR&O=JT&headerLivre=";

    HINTERNET hSession = InternetOpen(L"Mozilla/5.0", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
    if (!hSession) return false;

    HINTERNET hConnect = InternetConnect(hSession, L"scon.stj.jus.br", INTERNET_DEFAULT_HTTPS_PORT, L"", L"", INTERNET_SERVICE_HTTP, 0, 0);
    if (!hConnect) return false;

    HINTERNET hRequest = HttpOpenRequest(hConnect, L"POST", L"/SCON/pesquisar.jsp", NULL, NULL, NULL, INTERNET_FLAG_KEEP_CONNECTION, 0);
    if (!hRequest) return false;

    if (!HttpSendRequest(hRequest, L"Content-Type: application/x-www-form-urlencoded\r\n", -1, queryValues.c_str(), queryValues.size())) return false;

    //...

    InternetCloseHandle(hRequest);
    InternetCloseHandle(hConnect);
    InternetCloseHandle(hSession);

    return true;

}

让我们看一下同一页面上的另一个示例:

<form id="frmPesquisaProcHeader" action="https://ww2.stj.jus.br/processo/pesquisa/"
                                    method="get" name="frmPesquisaProcHeader" onsubmit="" target="_blank"
                                    style="display: none">
                                    <input name="termo" id="headerTermo" type="hidden" value="">
                                    <input name="aplicacao" value="processos.ea" type="hidden">
                                    <input name="tipoPesquisa" value="tipoPesquisaGenerica" type="hidden">
                                    <input id="chkordem" name="chkordem" value="DESC" type="hidden">
                                    <input id="chkMorto" name="chkMorto" value="MORTO" type="hidden">
                                </form>

请注意,此 Web 表单需要

GET
请求而不是
POST
,因此您需要在正文的 URL 本身中包含表单值,例如:

#include <windows.h>
#include <wininet.h>
#include <string>

#pragma comment (lib, "Wininet.lib")

bool GetRequest() {

    std::wstring queryValues = L"termo=&aplicacao=processos.ea&tipoPesquisa=tipoPesquisaGenerica&chkordem=DESC&chkMorto=MORTO";

    HINTERNET hSession = InternetOpen(L"Mozilla/5.0", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
    if (!hSession) return false;

    HINTERNET hConnect = InternetConnect(hSession, L"ww2.stj.jus.br", INTERNET_DEFAULT_HTTPS_PORT, L"", L"", INTERNET_SERVICE_HTTP, 0, 0);
    if (!hConnect) return false;

    HINTERNET hRequest = HttpOpenRequest(hConnect, L"GET", (L"/processo/pesquisa/?" + queryValues).c_str(), NULL, NULL, NULL, INTERNET_FLAG_KEEP_CONNECTION, 0);
    if (!hRequest) return false;

    if (!HttpSendRequest(hRequest, 0, 0, 0, 0)) return false;

    //...

    InternetCloseHandle(hRequest);
    InternetCloseHandle(hConnect);
    InternetCloseHandle(hSession);

    return true;

}

根据需要对您要提交的每个

<form>
重复此操作。 您需要使用指定的
<input>
确定必须发送到每个
action
url 的
method
值。

© www.soinside.com 2019 - 2024. All rights reserved.