面试官让我上机写一个爬虫,没有经验,写的也没什么价值,就是想记录一下
1.用WebRequest相关API抓取数据的时候会返回403服务器拒绝的问题。
经网上寻找解决方案,是用指定UserAgent参数伪装浏览器,并成功解决问题。
2.大众点评网上要抓取的数据是动态生成。抓取的Html内容中不包含想要获取的内容。
后来找到一个网友提供的思路: 用WinForm里的webBrowser控件,可以把网页内容全部 加载完后,再通过Document获取。并最终使用这种方式实现。
1 using System; 2 using System.Text; 3 using System.Windows.Forms; 4 5 namespace WindowsFormsApplication3 6 { 7 public partial class Form1 : Form 8 { 9 public Form1() 10 { 11 InitializeComponent(); 12 string url = "http://www.dianping.com/search/category/2/10/g110"; 13 webBrowser1.Navigate(url); 14 } 15 16 /// <summary> 17 /// 点击获取信息 18 /// </summary> 19 /// <param name="sender"></param> 20 /// <param name="e"></param> 21 private void btnGetInfo_Click(object sender, EventArgs e) 22 { 23 StringBuilder result = new StringBuilder(); 24 HtmlElementCollection lis = webBrowser1.Document.GetElementsByTagName("li"); 25 26 foreach (HtmlElement element in lis) 27 { 28 //最开始的三个 店铺信息 li class="top" 29 if (element.OuterHtml.Contains("li class=\"top\"")|| element.OuterHtml.Contains("li data-midas=")) 30 AppendResultInfo(result, element.InnerHtml); 31 } 32 33 this.textConent.Text = result.ToString(); 34 35 } 36 37 /// <summary> 38 /// 添加符合的信息到结果中 39 /// </summary> 40 /// <param name="result">结果数据</param> 41 /// <param name="InnerHtml">html内容</param> 42 private void AppendResultInfo(StringBuilder result, string InnerHtml) 43 { 44 result.Append("店名:").Append(GetMidStr(InnerHtml.Replace("a title=\"\"", ""), "<a title=\"", "\"")).Append("\n"); 45 result.Append("地址:").Append(GetMidStr(InnerHtml, "<span class=\"addr\">", "</span>")).Append("\n\n"); 46 } 47 48 /// <summary> 49 /// 获取中间的字符串 50 /// </summary> 51 /// <param name="inStr">源字符串</param> 52 /// <param name="startString">开始字符串</param> 53 /// <param name="endString">结束字符串</param> 54 /// <returns></returns> 55 private static string GetMidStr(string inStr, string startString, string endString) 56 { 57 int iBodyStart = inStr.IndexOf(startString, 0); //开始位置 58 if (iBodyStart == -1) 59 return null; 60 iBodyStart += startString.Length; //要查找的字符串起始位置 61 int iBodyEnd = inStr.IndexOf(endString, iBodyStart+1); 62 if (iBodyEnd == -1) 63 return null; 64 iBodyEnd += endString.Length; //要查找的字符串结束位置 65 string strResult = inStr.Substring(iBodyStart, iBodyEnd - iBodyStart - endString.Length); 66 return strResult; 67 } 68 69 70 } 71 }