网页抓取数据 免费(什么语言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(或微信),获取句柄,找到对象,动态写入文本,然后调用目标按钮触发事件。信息。

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线