网页抓取数据 免费(什么语言requesturl获取的数据都是不完整的?)
优采云 发布时间: 2021-10-26 00:11网页抓取数据 免费(什么语言requesturl获取的数据都是不完整的?)
我们知道,如果网页的数据没有通过http协议加载到页面中,或者ajax延迟将数据加载到页面中,这时候你的语言请求url获取的数据是不完整的。
说白了就是无法抓取到需要的目标数据,采用以下两种方法来处理:
方法一:WebBrowser延迟加载采集地址(线程等待)用js处理。
1.目标网址:顺便说一下,这个网站很强大。通过浏览器可以看到作者使用了很多方法来防止爬取和分析。ID复制、访问频率验证、js加密压缩、302跳转、多域配置、非常规命名、节点重复混淆等,市面上常规的方法基本都搞定了(当然我们可以到302跳转,然后爬行,没有问题,这里是非常规的方法)。
2. 如何获取他的数据,HttpWebRequest不工作,你会发现返回的htm为null,我没试过php。
3.通过winfrom的WebBrowser控件加载页面,然后WebBrowser和js交互获取页面数据,然后返回到winfrom控件层本身。
页面加载完成后,我们将js注入到这个页面中,然后通过js获取目标数据,然后将获取到的数据存储在页面上,然后再次调用注册的事件触发数据返回。
1. 在WebBrowser的DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)事件中注册js脚本:
//注册事件
HtmlElement tbOriginUrl = webBrowser1.Document.All["sn"];
tbOriginUrl.AttachEventHandler("onclick", new EventHandler(SetTextBox));
IHTMLWindow2 win = (IHTMLWindow2)this.webBrowser1.Document.Window.DomWindow;
var scriptcollect = @"var _items = $('.hm1 .hm a').map(function(idx, dom){
var url = $(dom).attr('href');
var like = $.trim($(dom).find('div:eq(1)>span').text().replace(' 人喜欢 ', ''));
var play = $.trim($(dom).find('.su>span').text().replace(' 次播放 ', ''));
var title = $(dom).find('p').text();
var img = $(dom).find('img').attr('name');
return url + '$' + like + '$' + play + '$' + title + '$' + img;
}).get().join('|');
$('#sn').val(_items);
setTimeout(function(){
document.getElementById(""sn"").click();
},2000);";
win.execScript(scriptcollect, "Javascript");
注意需要引入using mshtml;空间(在 Microsoft.mshtml.dll 中)
这个脚本的意思是:
1. 先注册输入框的点击事件
2.找到目标数据对象,然后构造需要的数据
3.将构造好的数据写入输入框
4. 触发输入的点击事件。注意不是立即触发,而是延迟2秒触发。这是非常重要的。
点击事件的具体方法是:
void SetTextBox(object sender, EventArgs e)
{
HtmlElement tbOriginUrl = webBrowser1.Document.All["sn"];
try
{
if (tbOriginUrl != null && tbOriginUrl.OuterHtml != null)
{
var temp = tbOriginUrl.OuterHtml.Trim() //
.Replace(" ", "")
.Replace("\" required> ", "");
this.textBox1.Text = temp.Trim();
analysis(temp.Trim());
pageidx++; //变更页码
}
}
catch (Exception ex)
{
LogHelp.Log(ex);
}
//调用下一个页面...
}
先获取目标输入框的数据,然后解析,再写入数据库。
这里有2个建议:
1. 解析得到的数据后,建议将其存储在内存级存储对象中,例如memcached,然后单独开启一个服务将memcached中的数据写入数据库(例如mysql),从而可以减少采集循环时间速度会更快;
2.如何触发循环去采集,我无法在SetTextBox方法的末尾重置WebBrowser的url,使其可以循环。但有一点非常重要。主人的站点会检查访问该站点的IP和频率,并且一般设置一个阈值。每次 WebBrowser 打开页面时,您都需要仔细调整间隔时间。这个建议是将它从 20 秒减少到一个合适的间隔。您可以等待相应的秒数,然后再允许 WebBrowser 打开新页面。在这里您可以添加一个技巧是在间隔时间中添加一个随机秒,以防间隔时间每次都相同。
方法二:
1.谷歌浏览器打开开发者调试面板(F12),切换到页面的sources部分,然后在Snippets中编写可以获取目标页面数据的js方法,具体数据结构模型需要自己整理。
2.winfrom 写了一个小程序,获取当前打开目标采集页面的浏览器的句柄,通过句柄找到对象,显然是1布写的js
然后通过win api调用run方法,然后在Console中得到结果。
该方法的难点在于调用windows api获取窗口并触发事件。如果你熟悉它,那就没有什么了。现在的各种QQ机器人或者微信自动发送的小机器人都是这个思路。打开QQ(或微信),获取句柄,找到对象,动态写入文本,然后调用目标按钮触发事件。信息。