开发工具:vs2017,sql server 2014
框架版本:.net framework 4.6.1
开发模式:三层、orm PetaPoco
思路:
爬虫最为关键的一环就是读取网页的源码,其核心内容也是对网页源码的处理,因此获取到完整的网页源码是极为重要的(或者是要爬取的信息列表源码)。通过对网页源码进行字符串的处理,以便于获取需要的字段信息。
1.分析网页网址
例:https://www.shicimingju.com/shicimark/aiqingshi_1_0__0.html
这个网址翻页时会发生变动如果是第6页,网址为:
https://www.shicimingju.com/shicimark/aiqingshi_6_0__0.html
这时候,写一个循环拼接网址即可
2.分析网页(通过webBrowser加载网页)
(1).首先获取详情页的网址链接,主要是对a标签的处理,并拼接出一个完整的详情页网址,入库
注:详情页指的是,比如逛淘宝时,你点进去查看的就是商品的详情
(2).通过webBrowser循环加载第一步收入的网址,并提取需要的信息(主要是通过对字符串的截取实现)
实现过程
1.创建一个winform窗体程序,使用webBrowser控件
页面加载实例代码
//阻止网页js弹窗
webBrowser1.ScriptErrorsSuppressed = true;
//加载网页
webBrowser1.Navigate("https://www.shicimingju.com/shicimark/aiqingshi_1_0__0.html");
//获取当前webBrowser加载的网页源码
string htmlString = webBrowser1.Document.Body.OuterHtml;
因为webBrowser控件的内核是ie,所以对网页的兼容性比较差,好多网址在这个控件中加载时,会有js的错误弹窗,影响程序运行,所以需要阻止弹窗的弹出。
2.获取详情页链接
我们在抓取链接时,抓取有效链接也是十分重要的,这样做有利于数据规范。一般详情页的链接都是有规律的,包含通用的关键字,比如list(https://www.shicimingju.com/chaxun/list/3227.html)
(1).使用正则表达式提取a标签的href
优点,通用性比较强(对于多个网站来说,可适用于多个网站的a标签链接的提取)
缺点,因各个网站的差异性,提取的链接可能不准确
(2).使用字符串截取的方式提取a标签的href
优点,截取比较准确(指定网站)
缺点,通用性较差
代码示例(我这里采用的是字符串截取的方式)
string htmlString = webBrowser1.Document.Body.OuterHtml;
string blUrl = "";
string[] collArray = Regex.Split(htmlString, "", RegexOptions.IgnoreCase);
for (int i = 0; i < collArray.Length - 1; i++)
{
try
{
//提取a标签
blUrl = HtmlUnscramble.GetValue(collArray[i], "href=\"", "\"");
if (blUrl == "") blUrl = HtmlUnscramble.GetValue(collArray[i], "href='", "'");
if (blUrl == "") blUrl = HtmlUnscramble.GetValue(collArray[i], "href=", " ");
if (blUrl.IndexOf("(") > -1 || blUrl.IndexOf("javascript") > -1 || blUrl.Length < 5) continue;
if (blUrl.Substring(0, 2) == "//") blUrl = "http:" + blUrl;
if (blUrl.Substring(0, 1) == "/" || blUrl.Substring(0, 1) == ".") blUrl = urlAdder + blUrl;
if (!blUrl.Substring(0, 5).Contains("http") && blUrl.Substring(0, 1) != "/" && blUrl.Substring(0, 1) != ".")
{
blUrl = urlAdder + "/" + blUrl;
}
if (blUrl.IndexOf(".com//") > -1) blUrl = blUrl.Replace(".com//", ".com/");
if (blUrl.IndexOf(".cn//") > -1) blUrl = blUrl.Replace(".cn//", ".cn/");
if (blUrl.IndexOf(".net//") > -1) blUrl = blUrl.Replace(".net//", ".net/");
blUrl = blUrl.Replace("&", "");
if (!blUrl.Contains(urlAdderKey)) continue;
string[] productKey = urlAdderKey.Split(';');
bool blProductKey = false;
for (int k = 0; k < productKey.Length; k++)
{
if (blUrl.Contains(productKey[k])) { blProductKey = true; };
}
//符合关键字入库
if (blProductKey)
{
int hrefcount = GSDA.GetGushi(blUrl);
if (hrefcount==0)
{
GuShiInfo guShiInfo = new GuShiInfo
{
Href = blUrl
};
GSDA.InGushi(guShiInfo);
}
}
}
catch
{
}
}
3.获取详情页数据信息
(1).加载详情页面
加载示例代码(这里加载时长我设置了1分钟,目的是确保网页源码的完整性)
#region Loading
///
/// 根据网址加载网页
///
/// 网址
public void Loading(string url)
{
bool loading = true; //表示正在加载
webBrowser1.Navigate(url);
DateTime dtime = DateTime.Now.AddMinutes(1);
while (loading)
{
Application.DoEvents();//等待本次加载完毕才执行下次循环.
if (DateTime.Now > dtime)
{
loading = false;
}
}
if (loading == false)
{
Application.DoEvents();//等待本次加载完毕才执行下次循环.
}
}
#endregion
(2).进行字符串处理,提取有效数据
数据提取代码示例(我这里使用的字符串截取的方式,也可使用正则)
IList<GuShiInfo> IGI = GSDA.GetAllGushi();
for (int i = 0; i < IGI.Count; i++)
{
Loading(IGI[i].Href);
html = webBrowser1.Document.Body.OuterHtml.ToLower();
title = HtmlUnscramble.GetValue(html, ""
, "");
concent = HtmlUnscramble.GetValue(html, "", "");
authorandyears = Regex.Split(HtmlUnscramble.GetValue(html, "", "",false), ", RegexOptions.IgnoreCase);
years = HtmlUnscramble.ClearStyle(authorandyears[0]);
author = HtmlUnscramble.GetValue(authorandyears[1], ">", "<");
shangxi = HtmlUnscramble.GetValue(html, "作品赏析 ", "");
IGI[i].Html = html.Replace("'","");
IGI[i].Title = title;
IGI[i].Author = author;
IGI[i].ShangXi = shangxi;
IGI[i].Years = years;
IGI[i].Concent = concent;
IGI[i].State = 1;
GSDA.UpdateGuShi(IGI[i]);
Random random = new Random();
int seconds = random.Next(1, 7) * 1000;
Thread.Sleep(seconds);
}
4.注意事项
(1).注意控制网页抓取速率,访问太频繁,会被网站反扒检测到,ip会被封掉。因此控制页面时长就很重要了!
(2).如果网站有json源数据,抓取这个也是可以的,后期会出一个json数据抓取案例。
(3).webBrowser 由于是ie内核,所以网站兼容性很差。可以使用谷歌内核的类似插件,如CefSharp,使用nuget包下载即可。后期会出一个简单的教程使用CefSharp制作爬虫