A.为什么要做这个功能?
最近微博和微信开放平台的二次开发整的貌似蛮火,但做过微博开放平台的二次开发的人都会知道,新浪提供的微博访问接口并不是那么完美,有众多限制(调用频率限制、接口级别限制),对于没有经过审核通过高级接口的用户而言,要想通过API来实现这个功能,我只能说一句呵呵。
B.实现方式与步骤?
1.WinForm
步骤1:调用内置控件WebBrowser对象来加载热门微博地址。
步骤2:
在后台用正则表达式解析要抓取HTML的片段,复杂的抓取往往需要程序员的正则表达式的掌握程度比较好。
步骤3:数据自由处理。
2.WebForm
对于正则表达式不熟的人来说,临时去学这个是需要点时间的,不过利用脚本的Dom操作一样可以完成HTML的规则匹配。那是不是直接把请求URL放到iframe标签src属性中,然后在父页面调用操作iframe页面的元素从而取到数据,就万事大吉了?呵呵,web开发人都知道有个蛋疼的问题叫:跨域访问,权限不足。网上一搜,目前找到的只有jquery.xdomainajax.js。有兴趣的可以查一下它的API,从这几次对这个插件的使用情况来看,并不乐观,原因是并非所有url的跨域请求都会得到相应的回报。
所以最终还是出了以下步骤:
步骤1:利用WebClient或者WebRequest或者HttpWebRequest请求热门微博地址,出于有些url的http请求的头Headers的必须有特殊要求,因此推荐选用HttpWebRequest。
步骤2:由于抓取的网址的返回的数据类型不定,它可能是一段html格式的文本,可能是一段具有json格式的文本,因此进行相应的转换后,我只取出最终需要解析的那部分HTML,下载到本地站点某文件夹下。
步骤3:下载完成html后,设置Iframe的src=该html文件的url路径,当iframe加载完成后执行Dom元素读取即抓取动作。
步骤4: 数据自由处理
C.碰到的问题与解决方案?
1.新浪微博的热门微博显示具有ajax滚动延迟加载效果,即当鼠标滚动到滚动条最底部则会异步刷新出之后的10条热门微博。若不进行相应处理,则只可能抓到用户还没有滚屏时候的微博,也就只有1页微博,那如何抓滚屏之后的微博呢?
Solution:利用Fildder,分析每次滚动时候请求的地址,是有规律可言的。并再次对该地址进行请求拿到新的请求的结果并处理。利用此方法均可解决网页在异步加载的数据的抓取问题。
2.抓取新浪热门话题url时,返回的json中没有数据,而用Fildder监控则存在数据
Solution:抓取热门话题时候,通过Fildder监控http headers发现X-Requested-With=XMLHttpRequest,必须在HttpWebRequest请求过程中把这个加到头部中:myReq.Headers.Add("X-Requested-With",
"XMLHttpRequest");