我想解析 Perekrestok 商店的网站。
https://www.perekrestok.ru/cat/c/104/rastitelnoe-maslo
我编写了代码,一切正常,我得到了 html,我使用正则表达式做了我需要的事情。一周过去了,代码停止工作。抛出异常 403。我添加了一个标头(假装是浏览器),然后它再次开始返回 html,但不是我需要的。之前收到一个1MB左右的大文本,就好像我在浏览器里右键,看页面代码一样。现在我得到了一个22kB的小东西,里面没有商品,它们的价格等等。不。通过浏览器,一切都有效并且仍然有效。如果该网站认为我在发送垃圾邮件,我会理解,但我每 2 天就会解析 15 个链接。我不知道在哪里附上“错误”html 的示例。在这里复制粘贴是不人道的
https://dropmefiles.com/N9fRZ(22kB 文本文件,内含 html)
您需要获得与点击链接、右键单击并单击“查看页面代码”或从中提取产品、价格等相同的 html。
var client = new HttpClient();
client.DefaultRequestHeaders.Add("User-Agent",
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36");
string html = await client.GetStringAsync("https://www.perekrestok.ru/cat/c/104/rastitelnoe-maslo");```
只有这个网站的作者才会回答你“为什么它有效然后不起作用”的答案,因为我们不知道那里有什么以及改变了什么,但我们可以知道现在有什么。嗯,现在有以下内容:
如果您仔细观察该网站的行为方式,您会注意到以下图片:
看到 2 个标记为 HTML 的请求吗?这就是该网站“幕后”所做的事情。当您第一次访问它时,您会收到一个“存根”页面,其中数据处理指示器在视觉上旋转,并且“在引擎盖下”生成了 2 个安装在浏览器 Cookie 中的唯一密钥。实际上,你现在卡在第一个请求上,因为请求的各种事情
HttpClient
都是干活,它们不会为你执行 JS 脚本(就像浏览器那样),你必须自己承担这项工作。其实,该怎么办呢?
选项 3。
Jint
,但请记住,部分逻辑放置在单独的第三方库中(在请求屏幕上位于 #15 下))WebView2
、Selenium
等)。我个人会走第一种路线,因为我认为它占用资源更少并且更可靠,并且在这个例子中没有什么特别复杂的。
我们手动生成必要的 Cookie
分析网站
首先,让我们以编程方式向站点发送请求:
并且...我们收到 403 错误。为什么?问题是该网站还会检查
UserAgent
,如果没有设置,那么该网站会立即停止让我们进入。实际上,我们像您一样添加它 (client.DefaultRequestHeaders.Add(...)
),然后重试。现在该网站为我们提供了必要的数据,我们查看它并了解那里发生了什么:从所有这些脚布中,我们需要负责
spid
和 的东西spsc
。第一个是在公共领域,我们只需要把它捡起来,但第二个是通过两种方法生成的get_cookie_spsc_uncrypted_part() + get_cookie_spsc_encrypted_part()
。让我们看看这些方法:
get_cookie_spsc_uncrypted_part
- 那里一片空白(也许很快就会出现)。get_cookie_spsc_encrypted_part
- 但这里更有趣的是,变量 中有一个私钥pem
,并且还使用 解密了某个长字符串KJUR.crypto.Cipher.decrypt(...);
。在这里,如果我们在互联网上稍微搜索一下,我们就会了解到某个字符串是用某个 RSA 密钥进行编码的,并且要重复这些操作,我们需要密钥本身和相应编码的字符串。以编程方式收集数据
分析完了,现在让我们来看看吧。在这个阶段我们已经有了 HTML,我们需要从中提取我们需要的内容,问题是如何提取?最简单的方法是
Regex
,但是如果您解析 HTML,那么您很可能有一种特殊的方法。此方法的库。为了简单起见,我将使用 bareRegex
。我将其添加到上面的代码中:顺便说一句,我注意到该网站并不总是给出以 开头的密钥
BEGIN RSA PRIVATE KEY
,有时它给出的密钥没有RSA
(BEGIN PRIVATE KEY
)。我在这里没有考虑到这一点,但你应该考虑。这段代码最终应该从 HTML 站点“剥离”我们需要的所有数据。还剩下一点点要做。
Cookie解密与生成
嗯,这里一切都很简单。
RSA
——using var rsa = RSA.Create();
Pem
-rsa.ImportFromPem(pemKey);
var encryptedData = Convert.FromHexString(encryptedDataHex);
var decryptedData = rsa.Decrypt(encryptedData, RSAEncryptionPadding.Pkcs1);
var spsc = Encoding.UTF8.GetString(decryptedData);
所有代码:
我们再次发送请求
我们已经成功收到了我们需要的
Cookie
,剩下的就是在新的请求中发送它们:Aaand...本站已成功提供数据,恭喜!
整个代码如下所示:
工作示例:dotnetfiddle