c# - 浏览 Javascript 生成的网页
问题描述
有这个在线表格(https://servizi.ivass.it/RuirPubblica/),您可以在其中进行搜索(只需进行空白搜索)。对于它给出的每个结果,我需要单击结果并导出详细信息页面第 5 个表中的列表。
所以基本上我想制作一个为我做这件事的软件:
- 使用我自己的条件提交搜索
- 访问结果项的每一页
- 访问每个项目的详细信息页面
- 获取第 5 个标签中的行,以便我可以将它们附加到列表中
当我单击“搜索”按钮时,我使用 Fiddler 检查了 POST 请求中使用了哪些参数,并尝试对 .Net 执行相同操作。如果我尝试使用 HttpClient 访问基址,它会返回搜索表单的正确 HTML,但是当我使用搜索参数提交以下 POST 请求时,我会得到一个显示错误“警告:会话已过期”的网页。
如果我在没有首先访问主页的情况下单独进行搜索 POST 调用,也会发生这种情况,所以我不确定它是否与保持两个请求之间的会话不存在有关。
public MainWindow()
{
InitializeComponent();
var cookieJar = new CookieContainer();
var handler = new HttpClientHandler
{
CookieContainer = cookieJar,
UseCookies = true,
UseDefaultCredentials = false
};
client = new HttpClient(handler)
{
BaseAddress = new Uri("https://servizi.ivass.it/RuirPubblica/Search.faces")
};
}
private async Task TryHttp()
{
// Access the search page
var response = await client.GetAsync(client.BaseAddress);
var responseString = await response.Content.ReadAsStringAsync();
// Perform the search
var values = new Dictionary<string, string>
{
{ "FormSearch", "FormSearch" },
{ "FormSearch:j_id_jsp_558348152_13", "PG" },
{ "FormSearch:j_id_jsp_558348152_16", "custom" },
{ "FormSearch:SecE", "on" },
{ "FormSearch:matricola", "" },
{ "FormSearch:ragioneSociale", "" },
{ "FormSearch:provincia", "NA" },
{ "FormSearch:SearchButton", "Ricerca" },
{ "javax.faces.ViewState", "j_id1:j_id5" },
};
var content = new FormUrlEncodedContent(values);
response = await client.PostAsync(client.BaseAddress, content);
// Here I'm getting a web page showing the error "Warning: Session expired"
responseString = await response.Content.ReadAsStringAsync();
}
private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
{
TryHttp();
}
解决方案
如果你能定义它,它就可以完成。正如您将从评论中了解到的那样,StackOverflow 都是关于编程问题的,所以我只会帮助您解决这个问题。
原则上,如果网页是“可解析”为 HTML 并使用 HTTP 进行通信,那么您可以用它做任何普通 Web 浏览器会做的事情。您引用的网站最初似乎确实做了任何不寻常的事情。
HTMLAgilityPack对于解析 DOM 以及导航和提取内容非常有用。
要使用 C# 发出 HTTP 请求,您应该使用HttpClient类。
有一些较旧的选项,例如HttpWebClient,这里有很好的答案,可以帮助您在两者之间做出决定。
为了快速参考,Fiddler 在这里可用,我也用过很多次并且会推荐它,尽管它可能会导致 HTTPS 流量和调试问题。