如何通过填充一些输入文本来抓取网站并单击 .NET Core C# 中的提交按钮

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

我正在抓取一个在经典 asp.net 中完成的网站。它有 2 个带 ID 的字段。一个是输入文本,另一个是按钮。我需要填写输入框并单击按钮。并得到回应。该按钮是提交类型。

我使用的是 HTML 敏捷包。但是仅仅填写输入框并点击按钮是不够的。

代码示例是: '

            <table class="MainTable">
                <tbody>
                <tr>
                    <td class="styleIndent">&nbsp;</td>
                    <td class="Labels"><span id="ctl00_MainContent_lblLastName" class="fieldHeader" for="ctl00_MainContent_txtLastName">Name:</span></td>
                    <td class="styleColumnBody">
                        <input name="ctl00$MainContent$txtLastName" type="text" value="sberbank" maxlength="250" id="ctl00_MainContent_txtLastName" tabindex="2" title="Enter name as search criteria." style="width:200px;">
                    </td>
                    <td class="Labels"><span id="ctl00_MainContent_lblCity" class="fieldHeader" for="ctl00_MainContent_txtCity">City:</span></td>
                    <td class="styleColumnBody">
                        <input name="ctl00$MainContent$txtCity" type="text" maxlength="250" id="ctl00_MainContent_txtCity" tabindex="6" title="Enter city name as search criteria." style="width:200px;">
                    </td>
                </tr>
                <tr>

                    <td class="Labels"></td>
                    <td style="text-align: left">
                        <input type="submit" name="ctl00$MainContent$btnSearch" value="Search" id="ctl00_MainContent_btnSearch" tabindex="9" style="font-weight:normal;height:22px;width:96px;">&nbsp;&nbsp;
                        <input type="submit" name="ctl00$MainContent$btnReset" value="Reset" id="ctl00_MainContent_btnReset" tabindex="10" style="font-weight:normal;height:22px;width:96px;">
                    </td>
                </tr>
            </tbody></table>

'

这是一个经典的 .Net,点击按钮即可重新加载页面 (ctl00_MainContent_btnSearch)。所以通过检查页面很难知道任何事情:

c# web-scraping .net-core buttonclick simulate
4个回答
1
投票

Html Agility Pack 旨在解析、查询和操作 HTML DOM。某种爬虫将是它的用例。但是你想实际run http 请求、javascript 事件或那些按钮后面的任何东西。具有大多数功能的最简单方法是远程控制网络浏览器。

首先安装 Selenium 和浏览器驱动程序。我在这里使用 Firefox,因为它是免费的、开源的并且关注隐私:

Install-Package Selenium.WebDriver
Install-Package Selenium.Firefox.WebDriver

下载浏览器的驱动程序可执行文件。 Firefox gecko 驱动程序可以在 github 上找到:https://github.com/mozilla/geckodriver/releases/download/v0.24.0/geckodriver-v0.24.0-win64.zip版本概述如果帖子变老:https //github.com/mozilla/geckodriver/releases

现在执行存档并将其路径复制到变量:

string geckoDriverPath = @"D:\Downloads\geckodriver-v0.24.0-win64";

我们准备开始使用 Firefox。一个简单的例子,在 stackoverflow 的搜索字段中输入一些查询,然后单击右侧的搜索按钮:

using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Support.UI;
using System;

class Program {
    static void Main(string[] args) {
        string geckoDriverPath = @"D:\Downloads\geckodriver-v0.24.0-win64";
        using (var driver = new FirefoxDriver(geckoDriverPath)) {
            driver.Navigate().GoToUrl("https://stackoverflow.com");
            var searchBox = driver.FindElementByCssSelector("#search .js-search-field");
            searchBox.SendKeys("Selenium");

            var searchButton = driver.FindElementByCssSelector("#search .js-search-submit");
            searchButton.Click();
            Console.Read();
        }
    }
}

请耐心等待,初始化浏览器可能需要几秒钟。

根据您点击按钮的作用,可能还有其他方法。如果是某种 http 请求(表单或 ajax 调用),您可以手动发送。这更快,节省资源,您可以轻松地无头运行它。但这更难实现。特别是在需要从页面源中提取 id 等数据的复杂页面上。如果你关心性能和资源,你可以考虑这个。


0
投票

如果表单是标准的HTML表单,可以获取post-back url,然后自己post表单数据。本质上,您正在执行按钮通常会执行的操作,而不是填写表单本身。

要使其正常工作,您需要发布到的 URL 以及发布回服务器的元素的名称。您可以通过任何 Web 检查器工具轻松获得它。拥有它后,您可以执行以下操作:

var request = (HttpWebRequest)WebRequest.Create(uri);
request.Method = HttpMethod.Post.ToString();
request.ContentType = "application/json";

// replace name1, name2, value1, value2 with the 
// key value pairs that need to be posted.
var content = $"{name1}={value1}&{name2}={value2}"

using (var writer = new StreamWriter(request.GetRequestStream()))
{
    writer.Write(content);
}

request.ContentLength = content.Length;
using (var response = (HttpWebResponse)request.GetResponse())
{
    var encoding = Encoding.GetEncoding(response.CharacterSet);

    using (var responseStream = response.GetResponseStream())
    {
        using (var reader = new StreamReader(responseStream, encoding))
        {
            return reader.ReadToEnd();
        }
    }
}

如果您使用的是 .NET 4.5 或更高版本,您可以使用 HttpClient 类,这使这变得更加简单:

var httpClient = new HttpClient();
response = await httpClient.PostAsync(uri, new StringContent(data));

response.EnsureSuccessStatusCode();

string content = await response.Content.ReadAsStringAsync();

0
投票

使用 headless chrome 怎么样?您可以导航到网页并根据需要进行任何操作。

https://github.com/kblok/puppeteer-sharp

// lauch browser and save in variable
var _browser = await Puppeteer.LaunchAsync(new LaunchOptions
{
    Headless = true,
    ExecutablePath = _config.ChromePath, // get path to chrome executable
});
// go to page
var _page = await _browser.NewPageAsync();
var page.GoToAsync("http://www.example.com");

// click on form input 
await _page.ClickAsync("#name");
// set data
await _page.Keyboard.SendCharacterAsync("John");
// submit form
await _page.ClickAsync("#SubmitButton");

0
投票
  1. 首先,您需要在项目中安装Selenium WebDriver NuGet 包。您可以使用以下命令从 NuGet 控制台执行此操作:

    安装包 Selenium.WebDriver

  2. 在您的控制器中,您可以定义一个操作,该操作接收要搜索的 ID 号并使用 Selenium WebDriver 导航到搜索页面、填写表单并获取结果。这是此操作的示例:

     public IActionResult Index()
     {
         var userAgent = HttpContext.Request.Headers["User-Agent"];
         return View();
     }
     public IActionResult Search(string dni)
     {
         var options = new ChromeOptions();
         options.AddArgument("headless");
         options.AddArgument("disable-gpu");
         IWebDriver driver = new ChromeDriver(options);
         try
         {
             // Navegar a la página de búsqueda
             driver.Navigate().GoToUrl("https://eldni.com/pe/buscar-por-dni");
    
             // Llenar el formulario con el número de DNI
             var inputElement = driver.FindElement(By.Name("dni"));
             inputElement.SendKeys(dni);
    
             // Hacer clic en el botón de búsqueda
             var buttonElement = driver.FindElement(By.XPath("//button[contains(@class, 'btn-success')]"));
             buttonElement.Click();
    
             //// Esperar a que la página de resultados cargue completamente
             WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
             IWebElement resultsElement = wait.Until(ExpectedConditions.ElementIsVisible(By.Id("div-copy")));
    
             // Obtener los resultados
             string nombre = resultsElement.FindElement(By.Id("nombres")).GetAttribute("Value");
             string apellidop = resultsElement.FindElement(By.Id("apellidop")).GetAttribute("Value");
             string apellidom = resultsElement.FindElement(By.Id("apellidom")).GetAttribute("Value");
    
             // Devolver los resultados en la vista
             return Json(new { Nombre = nombre, ApellidoP = apellidop, ApellidoM = apellidom });
         }
         finally
         {
             // Cerrar el navegador
             driver.Quit();
         }
     }
    
  3. 在你的视图中,可以显示上一步得到的结果:

$(document).ready(function () {
        $("#searchButton").click(function () {
            var dni = $("#dni").val();

            $.ajax({
                type: "POST",
                url: "/Controller/Search?dni=" + dni,
                success: function (data) {
                    $("#resultado").html(
                        "<br><br>" +
                        "<h3>RESULTADO</h3>" +
                        "<table class='table-bordered table-striped' style='width: 100%' >" +
                        "<thead><tr><th>NOMBRES</th><th>A. PATERNO</th><th>A. MATERNO</th></tr></thead>" +
                        "<tbody><tr><td>" + data.Nombre + "</td><td>" + data.ApellidoP + "</td><td>" + data.ApellidoM + "</td></tr></tbody>" +
                        "</table>"
                    );
                }
            });
        });
    });
<div class="form-group">
<label for="dni">DNI: </label>
<input type="number" class="form-control" id="dni" name="dni" maxlength="8" value="@Model" oninput="javascript: if (this.value.length > this.maxLength) this.value = this.value.slice(0, this.maxLength);">
</div>
<button type="button" class="btn btn-primary" id="searchButton">Consultar Datos</button>
<div id="resultado"></div>

希望对你有帮助。问候

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