Próbuję automatycznie wypełnić formularz interaktywny na stronie www umieszczonej WebBrowser. Formularz działa w taki sposób, że na stronie jest 50 pól tekstowych oraz przycisków. Na początku widać tylko jedno pole tekstowe i przycisk, a reszta ma własność "display" ustawioną na "none". Po wpisaniu tekstu i wciśnięciu pierwszego przycisku, poprzez ajax, zostaje wysłane zapytanie do serwera. Po bliżej nieokreślonym czasie (od 0,5 do 10 sekund), po utrzymaniu odpowiedzi, kolejne pole tekstowe i przycisk mają własność "display" ustawioną na "block". I tak 49 razy. Jestem w stanie bez problemu wprowadzić dane do wybranego pola tekstowego i zasymulować wciśnięcie przycisku, ale nie umiem poczekać zanim kolejne elementy formularza będą widoczne. Próbuję to zrobić w taki sposób, że chcę sprawdzać czy własność "display" następnego przycisku, czy jest równa "block". Jeżeli tak, to wypełnij pole i wciśnij przycisk. Problem w tym, że użycie jakiejkolwiek pętli, w której sprawdzana jest własność display, zatrzymuje wykonywanie strony w WebBrowser.
A ta pętla jest w JS? Jak tak, to musisz używać setTimeout.
Po bliżej nieokreślonym czasie (od 0,5 do 10 sekund), po utrzymaniu odpowiedzi, kolejne pole tekstowe i przycisk mają własność "display"
Wyjatkowo upierdliwa strona
Jestes w stanie odpalic skrypt js na tej stronie? Ustaw wszystko na display block
Pętla jest w C#. Nie mam dostępu do kodu strony www. Celem jest zrobienie automatu, który wypełni formularz za człowieka. Jeszcze jedna ważna sprawa. W trakcie wykonywania zapytania, pomiędzy kolejnymi etapami wyświetlany jest element
https://code.msdn.microsoft.com/windowsapps/How-to-inject-javascript-f3970459
Edit: jsem mozesz manipulowac DOMem i ustawic display jaki chcesz
Edit2: mozesz tez po prostu zobaczyc jak wygladaja requesty do serwera i je wykonywac bez zbednego posrednictwa front-endu
To co zostanie wprowadzone do kolejnych pół formularza jest ściśle uzależnione od odpowiedzi z serwera na poprzednie zapytanie. Dlatego nie mogę wprowadzić wszystkich naraz.
Bednarus3 napisał(a):
To co zostanie wprowadzone do kolejnych pół formularza jest ściśle uzależnione od odpowiedzi z serwera na poprzednie zapytanie. Dlatego nie mogę wprowadzić wszystkich naraz.
Moze znajdz skrypt ktory to obsluguje (pewnie jakis ajax) i zmodyfikuj do swoich celow zeby od razu po odpowiedzi serwera triggerowal sie nastepny stage twojego skryptu.
W sensie zmodyfikuj i podmien
Skrypt do obslugi musi byc jawny bo to front-end. Najwyzej moze byc zminimalizowany (beautifier rozwiazuje problem) albo zobfuskowany
Edit: a juz jak sie tak chcesz bawic to i tak lepiej w jsie a nie C#
To jest jedna opcja, żeby wstrzyknąć javascript, a potem wywołać funkcję i jako parametr podać dane do wprowadzenia w formularzu. Jednakże wolałbym w C# mieć równolegle działającą kontrolkę WebBrowser razem z metodą, która będzie sprawdzała stan strony www i w odpowiednim momencie wprowadzała dane.
Użyj Selenium.
IWebDriver driver = new ChromeDriver();
string url = "https://www.google.com";
IWebElement textBox;
driver.Navigate().GoToUrl(url);
textBox = driver.FindElement(By.Name("username"));
textBox.SendKeys("Test text");
Jeżeli nie chcesz aby odpalała Ci się przeglądarka Chrome/Firefox, itd. to możesz odpalić z parametrami typu --headless
Ogarnąłem temat. Obsługę wypełniania pól i wciskania przycisków umieściłem w BackgroundWorker. Teraz asynchronicznie do WebBowser następuje sprawdzanie czy pojawiły się kolejne elementy na stronie.
@Bednarus3: możesz rzucić jakiś kod? Dane wrażliwe, jeśli są, wytnij oczywiscie...
<!DOCTYPE html>
<html lang="pl">
<head>
<meta charset="utf-8">
<title>test</title>
<style>
</style>
<script>
function sendRequest(elementNo)
{
if (window.XMLHttpRequest) {
// code for IE7+, Firefox, Chrome, Opera, Safari
xhr = new XMLHttpRequest();
} else {
// code for IE6, IE5
xhr = new ActiveXObject("Microsoft.XMLHTTP");
}
xhr.onreadystatechange = function()
{
if (xhr.readyState == 4 && xhr.status == 200)
{
document.getElementById("rt").innerHTML = "Czas odpowiedzi: " + xhr.responseText;
if (elementNo < 9)
{
elementNo ++;
document.getElementById("text" + elementNo).style.display = "block";
document.getElementById("button" + elementNo).style.display = "block";
}
}
};
xhr.open("POST", "skrypt.php");
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhr.send(document.getElementById("text" + elementNo).value);
}
</script>
</head>
<body>
<p id="rt">Czas odpowiedzi: </p>
<input type="text" id="text0" style="display: block">
<button type="button" id="button0" style="display: block" onclick="sendRequest(0)">Prześlij</button>
<input type="text" id="text1" style="display: none">
<button type="button" id="button1" style="display: none" onclick="sendRequest(1)">Prześlij</button>
<input type="text" id="text2" style="display: none">
<button type="button" id="button2" style="display: none" onclick="sendRequest(2)">Prześlij</button>
<input type="text" id="text3" style="display: none">
<button type="button" id="button3" style="display: none" onclick="sendRequest(3)">Prześlij</button>
<input type="text" id="text4" style="display: none">
<button type="button" id="button4" style="display: none" onclick="sendRequest(4)">Prześlij</button>
<input type="text" id="text5" style="display: none">
<button type="button" id="button5" style="display: none" onclick="sendRequest(5)">Prześlij</button>
<input type="text" id="text6" style="display: none">
<button type="button" id="button6" style="display: none" onclick="sendRequest(6)">Prześlij</button>
<input type="text" id="text7" style="display: none">
<button type="button" id="button7" style="display: none" onclick="sendRequest(7)">Prześlij</button>
<input type="text" id="text8" style="display: none">
<button type="button" id="button8" style="display: none" onclick="sendRequest(8)">Prześlij</button>
<input type="text" id="text9" style="display: none">
<button type="button" id="button9" style="display: none" onclick="sendRequest(9)">Prześlij</button>
</body>
</html>
<?php
$s = rand (4, 8);
sleep($s);
echo $s;
?>
using System;
using System.Windows.Forms;
namespace webbrowser_test
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
backgroundWorker1.RunWorkerAsync(webBrowser1.Document);
}
private void backgroundWorker1_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
{
string[] values = { "aa", "bb", "cc", "dd", "ee", "ff", "gg", "hh", "ii", "jj" };
int itemsQnty = 10;
HtmlDocument htmlDoc = (HtmlDocument)e.Argument;
for (int elementNo = 0; elementNo < itemsQnty; elementNo++)
{
htmlDoc.GetElementById("text" + elementNo.ToString()).SetAttribute("value", values[elementNo]);
htmlDoc.GetElementById("button" + elementNo.ToString()).InvokeMember("Click");
if (elementNo < itemsQnty - 1)
{
while (!isDisplayed(htmlDoc, (elementNo + 1))) ;
}
}
}
private bool isDisplayed(HtmlDocument htmlDoc, int elementNo)
{
return htmlDoc.GetElementById("button" + elementNo.ToString()).Style.Contains("DISPLAY: block");
}
}
}