2017-02-13 57 views
2

Qt 5.5.1을 사용하고 있습니다. QWebview를 사용하여 작은 브라우저를 만듭니다.
웹 페이지를 열고 버튼을 누르면, 내가 로그인 할 때 URL이 변경되지 않도록 로그인 페이지가있는 웹 사이트에서 데이터를 가져오고 싶으므로 QnetworkAccessManager에서 메소드를 사용하는 것과 같은 웹 사이트가 있습니다. 데이터를 가져 오기 위해 PHP에 메소드를 게시하지 않았습니다.
예를 들어 www.login.com에 로그인 할 때 로그인 데이터가 동일한 링크에 표시됩니다
이 문제를 해결할 수있는 아이디어가 있거나 웹 사이트에서 현재 데이터를 가져올 수있는 경우 QWebview
참고 내가 로그인 데이터가 소스 코드에 표시 파이어 폭스에서 소스보기 코드를 눌러하여에서 데이터를 웹 사이트에 로그인하여 얻을

이것은 내가 뭘하려
Qt를 사용하여 QWebView에서 웹 사이트 콘텐츠 가져 오기 5.5.1

MainWindow::MainWindow(QWidget *parent) : 
    QMainWindow(parent), 
    ui(new Ui::MainWindow) { 
     ui->setupUi(this); 
     ui->webView->load(QUrl("https://www.login.com")); // load page that have user name and password field 
     QWebPage *page = ui->webView->page(); // get the current page 
     manager = page->networkAccessManager(); // get the access manager from this page 
    } 

    MainWindow::~MainWindow() { 
     delete ui; 
    } 
    // get button 
    void MainWindow::on_pushButton_clicked() { 
     reply = manager->get(QNetworkRequest(QUrl("https://www.login.com"))); // make get now after login 
     connect(reply, SIGNAL(readyRead()),this,SLOT(readyRead())); 
     connect(reply, SIGNAL(finished()),this, SLOT(finish())); 
    } 

    void MainWindow::readyRead() { 
     QString str = QString::fromUtf8(reply->readAll()).trimmed(); // read the data 
     ui->plainTextEdit->appendPlainText(str); 
    } 

하지만, 첫 번째 페이지의 데이터를 가져옵니다. e 로그인없이. 로그인 후 페이지 콘텐츠를 가져오고 싶습니다. 제게해야 할 일에 대한 힌트를주세요.
갱신
는 내가 그것의 이름을 가지고 HTML 코드의 부분이 로그인없이 텍스트 입력 이름을 가져 그 결과가 여기에 포스트를 만들기 위해 QUrlQuery를 사용하여 첫 번째 페이지를 파이어 폭스에서 페이지 소스 코드를했다보기

<label class="label-off" for="dwfrm_ordersignup_orderNo">Numéro de la commande</label> <input class="textinput required" id="anyname" type="text" name="UserName" value="" maxlength="2147483647" placeholder="* UserName" data-missing-error="Saisis ton numéro de commande. " data-parse-error="Ce contenu est invalide" data-range-error="Ce contenu est trop long ou trop court" required="required" /> 

이며 다른 필드에는 동일한 코드가 있습니다.
코드 나는

manager = new QNetworkAccessManager(this); 
QUrlQuery query; 
query.addQueryItem("UserName", "AAAA"); 
query.addQueryItem("Password", "BBB"); 
reply = manager->post(QNetworkRequest(QUrl(ui->lineEdit->text().trimmed())), query.toString().toUtf8()); 
connect(reply,&QNetworkReply::downloadProgress,this,&MainWindow::progress); 
connect(reply,SIGNAL(readyRead()),this,SLOT(readyRead())); 
connect(reply, SIGNAL(finished()), this,SLOT(finish())); 

은 내가 만든 그것이 내가 다른 접근 방식을 사용하는 경우에만 HTML 페이지

+1

에게 등, 당신은 로그인 페이지를 사용자 환경에 코드를 적용 분석 할 필요가 있음을 유의하시기 바랍니다 간단한 예를 참조 webview->page()->mainFrame()->toHtml()

를 사용할 수있는 충분한 경우 아마도 POST 메소드를 서버에 보내려면 로그인 페이지를 분석하고 텍스트 입력의 이름을보고이를 'QUrlQuery'의 키로 전달하여 해당 값 (일반적으로 이름과 비밀번호)을 전달해야합니다. Qt로 post 메서드를 수행하는 방법의 예가 게시되었습니다 (http://stackoverflow.com/a/7445752/2014561). –

+0

나는 무엇을 시도했는지에 대한 질문을 업데이트한다. –

+1

내 대답을 참조하십시오. –

답변

1

의 문제는 여기에 작동 PHP 페이지와 우편 번호를 시도 게시물을 만들기 위해 Qt를에 사용하기 위해 대신 POST 요청을 시뮬레이트하기 위해 보통 QWebView으로 로그인 페이지를로드하고 Qt를 사용하여 사용자 이름, 비밀번호를 입력하고 제출 버튼을 위조 클릭하십시오.

로그인 후 페이지를 저장하는 방법에 대해 HTML 코드가 아닌 내용을 저장하는 방법에 대해 Qt에서 제공하는 좋은 방법은 HTML 코드를 잃어 버리는 단점이있는 웹보기를 PDF로 렌더링하는 것입니다.

코드 만하면,

void MainWindow::start() 
{ 
    connect(webview, &QWebView::loadFinished, this, &MainWindow::LogIn); 

    QString html = "<html>" 
        "<body>" 
        "<form action=\"https://httpbin.org/post\" method=\"POST\">" 
        "Username:<br>" 
        "<input type=\"text\" name=\"usernameinput\" value=\"abc\">" 
        "<br>" 
        "Password:<br>" 
        "<input type=\"password\" name=\"passwordinput\" value=\"123\">" 
        "<br><br>" 
        "<button name=\"button1\">Submit</button>" 
        "</form>" 
        "</body>" 
        "</html>"; 

    webview->setHtml(html); //Load yours https://www.login.com, using setHtml just for example 
} 

void MainWindow::LogIn(bool ok) 
{ 
    disconnect(webview, &QWebView::loadFinished, this, &MainWindow::LogIn); //Disconnect the SIGNAL 

    if (!ok) 
     return; 

    QWebElement document = webview->page()->mainFrame()->documentElement(); 

    QWebElement username = document.findFirst("input[name=usernameinput]"); //Find the first input with name=usernameinput 

    if (username.isNull()) 
     return; 

    username.setAttribute("value", "def"); //Change the value of the usernameinput input even 
              //if it already has some value 

    QWebElement password = document.findFirst("input[name=passwordinput]"); //Do the same for password 

    if (password.isNull()) 
     return; 

    password.setAttribute("value", "123456"); //Do the same for password 

    QWebElement button = document.findFirst("button[name=button1]"); //Find the button with name "button1" 

    if (button.isNull()) 
     return; 

    connect(webview, &QWebView::loadFinished, this, &MainWindow::finished); 

    button.evaluateJavaScript("this.click()"); //Do a fake click on the submit button 
} 

void MainWindow::finished(bool ok) 
{ 
    disconnect(webview, &QWebView::loadFinished, this, &MainWindow::finished); 

    if (!ok) 
     return; 

    QByteArray data; 
    QBuffer buffer(&data); 

    if (!buffer.open(QIODevice::WriteOnly)) 
     return; 

    QPdfWriter pdfwriter(&buffer); 

    pdfwriter.setResolution(100); //In DPI 

    webview->page()->setViewportSize(QSize(pdfwriter.width(), pdfwriter.height())); 

    QPainter painter; 
    painter.begin(&pdfwriter); 
    webview->page()->mainFrame()->render(&painter); 
    painter.end(); 

    buffer.close(); 

    qDebug() << "PDF Size:" << data.size(); //Now you have a PDF in memory stored on "data" 
} 
+0

답장을 보내 주신 데 대해 감사 드리며이 코드를 사용해 주셔서 감사합니다. 로그인 페이지에 사용자 이름과 암호가없는 클릭 버튼이 표시된 입력란이 포함 된 pdf 파일을 만들었습니다.나는 submit 버튼의 타입이 이 아니라는 것을 발견 한 소스 코드를 확인했다.

+0

코드에서 버튼 클릭을 수행하는 방법이 있습니까? 어쩌면 제출 유형이 이 아니고

+0

네, type = submit이거나 버튼, 하이퍼 링크 인 경우 객체에 따라 다릅니다. 객체의 고유 식별자를 찾아서 findFirst에 전달해야합니다. button이 name = button1 인 예제를 보여주기 위해 내 대답을 편집했습니다. –