WebClient 中的 C# 背靠背请求

C# back to back requests in WebClient

我正在开展一个项目,该项目通过网络抓取 table 进行工作。我尝试使用 C# WebClient 库连接到的网站无法正常工作,因为我需要先连接到该网站,然后模拟单击 "Next button" 以转到 table 中的下一页。

我现在使用的代码如下所示,

这是在查找名称时连接到网站:

    string urlParams = "lastName=John&firstName=Doe&PropertyID=&Submit=Serch+Properties"
    using(WebClient client = new WebClient())
    {
        client.Headers[HttpRequestHeader.ContentType] = "application/x-www-form-urlencoded";
        htmlResult = client.UploadString(url, urlParams);
    }

然后,一旦我进行了初始搜索,我就会查看是否可以使用 HtmlAglitityPack 单击下一步。如果可以的话,我会尝试在 url.

中发送参数
    HtmlDocument doc = new 
    doc.LoadHtml(htmlResult);

    // I get the xpath from google chrome dev tools, inspect element and right click copy xpath
    HtmlNode nextButton = doc.DocumentNode.SelectNode(selectNodeXPath);
    if(nextButton && nextButton.InnerHtml == "Next")
    {
        // right now just trying to see the second page.
        urlParams = "lastName=John&firstName=Doe&PropertyID=&Submit=Serch+Properties&SearchLocation=" + 1;
        client.Headers[HttpRequestHeader.ContentType] = "application/x-www-form-urlencoded";
        htmlResult = client.UploadString(url, urlParams);
    }

执行此操作后,htmlResult 为空。

如果数据库是远程 SQL 服务器数据库,那么您可以通过选择 "Code First from Database" 选项将数据库添加到您的项目中:

  1. 项目 -> 添加新项目...
  2. Select 来自左侧菜单的数据,然后是 ADO.NET 实体数据模型
  3. 输入 BloggingContext 作为名称并单击“确定”
  4. 这将启动实体数据模型向导
  5. Select 从数据库中首先编码然后单击下一步
  6. 输入数据库连接详细信息并完成...

然后当您想要查询数据库时,您将实例化向导生成的派生 DbContext class。

. . .
using (var ctx = new BloggingContext()) 
{
    var members = ctx.Members.Where(x => x.LastName = "Jones");
}
return members;
. . . 

The BloggingContext can be found by searching for ": DbContext" in your entire solution.

谷歌搜索后,我找到了答案,发现我的第一种方法确实不可行。

我下载并安装了 fiddler,这样我就可以看到我的确切网络流量,并让我了解我需要如何设置我的请求方法。

我是如何使用 fiddler 的:

  1. 连接到网站,输入搜索(在我的例子中是名字和姓氏字段)
  2. 点击搜索
  3. 看看fiddler帮我记录的web流量,看看调用的参数是什么,复制哪个。
  4. 单击下一步按钮
  5. 重复步骤 3。

开始我从使用 WebClient 切换到 HttpClient 并结合了 KeyValuePairs

代码基本上是两步。建立初始连接并为搜索结果中的每个页面提供一个新的键值对。

基本代码如下所示。


步骤 1) 建立初始连接

HttpClientHandler httpClientHandler = new HttpClientHandler();
HttpClient client = new HttpClient();

//Manulally contruct the request header
var stringContent = new FormUrlEncodedContent(new[]
{
    new KeyValuePair<string, string>("hJava", "Y"),
    new KeyValuePair<string, string>("SearchFirstName", firstName),
    new KeyValuePair<string, string>("SearchLastName", lastName),
    new KeyValuePair<string, string>("HomeState", state),
    new KeyValuePair<string, string>("frontpage", "1"),
    new KeyValuePair<string, string>("GO.x", "0"),
    new KeyValuePair<string, string>("GO.y", "0"),
    new KeyValuePair<string, string>("GO", "Go")
});

var response = client.PostAsync(url, stringContent).Result;
var initialSearch = response.Content.ReadAsStringAsync().Result;

步骤 2) 使用相同的 HttpClient 实例,创建一个类似于第一个请求的新请求,但添加了用于单击下一步按钮的部分

// New request header to filter our initial search results 
var stringContent = new FormUrlEncodedContent(new[]
{
     new KeyValuePair<string, string>("hJava", "Y"),
     new KeyValuePair<string, string>("searchLocation", "1"),
     new KeyValuePair<string, string>("SearchFirstName", firstName),
     new KeyValuePair<string, string>("SearchLastName", lastName),
     new KeyValuePair<string, string>("SearchStateID", state),
     new KeyValuePair<string, string>("GO.x", "0"),
     new KeyValuePair<string, string>("GO.y", "0"),
     new KeyValuePair<string, string>("GO", "Go")
 });

 var response = client.PostAsync(url, stringContent).Result;
 var nextSearch = response.Content.ReadAsStringAsync().Result;

就是这样。您可以对搜索结果的所有页面执行此操作。只需更改 new KeyValuePair<string, string>("searchLocation", "1"),在此示例中,我会将 1 更改为 2