李金峰 郭冰 李金隆
摘要:ScapySharp由于有一个浏览器包装类和使用类似jQuery的Css选择器和Linq语法,使得它使用简单,更容易地被用以进行Html文档解析。本文介绍了一种基于ScrapySharp的孔夫子旧书网的图书价格信息抓取器及其实现的思路和关键技术。
关键词:ScapySharp;孔夫子旧书网;图书价格;信息抓取
一、引言
采集电商网的商品价格信息,对于网店卖家进行同类商品的定价决策有重要的参考意义。笔者使用ScrapySharp实现了对孔夫子旧书网上的图书的价格信息进行抓取的软件,该软件功能可以用在电商系统后台等软件系统,为卖家的商品定价决策提供支持。
二、软件功能描述
卖家在孔夫子旧书网上架旧书商品的时候,需要确定旧书商品的价格,而价格的确定又需要参考同行的图书商品的定价。这种情况,一般的做法是通过图书的ISBN号在孔夫子旧书网上搜索图书的商品信息,然后查看各卖家对该书的定价,在参考同行定价的基础上,确定本店的定价。通过ISBN号在孔夫子旧书网上查询图书价格信息的方法如图1所示。这种查询图书定价信息的做法的最大缺点是,人力成本高,信息获取的效率低。
为了节约人力成本,提高查询网店图书价格信息的效率,笔者实现了一种基于ScrapySharp的孔夫子旧书网价格信息抓取器,用户只需要输入图书的ISBN号,就可以查找到孔夫子网上的该书的所有定价信息,并把定价信息显示在用户界面。
三、软件功能的实现
1、软件功能实现的思路
孔夫子旧书网的书籍价格信息抓取器的实现思路是,通过Url定位到图书查询的网页,然后对网页的内容进行抓取,最后从网页内容中把图书的价格信息提取出来。软件功能实现的思路(价格信息获取的流程)如图2所示。
2、以ISBN查询图书信息的Url分析
以ISBN为“9787560544588”的图书为例,该图书的中文书名为:概率、变量与过程(第4版);英文书名为:Probability,Random Variables and Stochastic Processes.在孔夫子旧书网的商品搜索框中输入“9787560544588”后,页面呈现搜索结果——《概率、变量与过程(第4版)》的商品信息列表,如图1所示。此时,浏览器地址栏中显示的网址为:http://search.kongfz.com/product/zk39k37k38k37k35k36k30k35k34k34k35k38k38/。
再通过其它图书的ISBN搜索实验发现,搜索结果地址的结构分为三部分,第一部分为服务器(控制器)地址,即:http://search.kongfz.com/product/。第二部分為经过字符串混淆处理的ISBN号,即例子中的网址的“zk39k37k38k37k35k36k30k35k34k34k35k38k38”部分,该部分的结构为:“zk3”+ISBN号第1位+“k3”+ISBN号第2位++“k3”+ISBN号第3位+“k3”+ISBN号第4位+“k3”+ISBN号第5位+“k3”+ISBN号第6位+“k3”+ISBN号第7位+“k3”+ISBN号第8位++“k3”+ISBN号第9位+“k3”+ISBN号第10位+“k3”+ISBN号第11位+“k3”+ISBN号第12位+“k3”+ISBN号第13位。第三部分为搜索结果的分页页码,由“w+数字”构成,数字1表示搜索结果的第一页,2表示第二页,以此类推。本例子中,网址可以写成完整结构(包含服务器(控制器)地址、ISBN号信息和搜索结果分页页码三部分)的网址,即:
http://search.kongfz.com/product/zk39k37k38k37k35k36k30k35k34k34k35k38k38w1/
通过实验发现,当输入的分页页码数大于实际搜索结果的分页页码时,返回的网页中的title标签中的内容为“搜索零结果”,即:
据此,可以准确判断搜索结果的分页页码数。
3、ScrapySharp和Htlm文档解析
通过网页搜索实验发现,图书价格信息在Html文档中的标签节点为:
遍历文档中的class为“red”的p标签可以获取当前页中的所有图书价格信息。
ScrapySharp为.Net开发者解析Html文档提供了极大的便利,主要优点有:ScapySharp有一个浏览器包装类(处理Reference,Cookie等),此外,它使用类似jQuery的Css选择器和Linq语法。通过ISBN号获取孔夫子旧书网中的图书价格信息的核心代码如下:
public List
{
try
{
//价格信息集合
List
//搜索结果分页
int page = 1;
//读取所有分页的html文档信息
while(true)
{
//使用WebClient处理从web站点检索的数据
WebClient client = new WebClient();
//获取搜索内容为isbn(图书ISBN号)的搜索结果网址
string address = GetSearchUrl(isbn);
//获取流
Stream st = client.OpenRead(address + “w” + page);
//分页页码加1
page++;
//创建StreamReader 对象
StreamReader sr = new StreamReader(st,Encoding.UTF8);
//获取html文档内容
string content = sr.ReadToEnd();
//创建HtmlDocument对象
var htmlDocument = new HtmlDocument();
//载入html文档内容到HtmlDocument对象中
htmlDocument.LoadHtml(content);
//获取html文档的标签节点
var html = htmlDocument.DocumentNode;
//如果输入的分页页码超出实际搜索结果的分页页码的范伟,则退出循环
if(html.CssSelect(“title”).FirstOrDefault().InnerHtml.Equals(“搜索零结果”))
{
break;
}
//获取class为red的p标签节点(即价格信息标签节点)
var prices = html.CssSelect(“p.red”);
//将价格信息保存到自定义的集合中
foreach(var htmlNode in prices)
{
priceStrList.Add(htmlNode.InnerHtml);
}
}
return priceStrList;
}
catch(Exception ex)
{
throw ex;
}
}
4、效果測试
在.Net控制台项目中对上述代码进行测试,测试实例为抓取ISBN号为“9787302423287”的图书的价格信息。测试程序的代码如下:
//实例化孔夫子图书价格抓取辅助类的对象
KongfuziPriceHelper helper = new KongfuziPriceHelper();
//调用GetKongfuziPriceByIsbn方法抓取图书的价格信息
List
//价格记录数
int count = 0;
//在控制台中输出所有价格
foreach(var item in priceStrList)
{
count++;
Console.WriteLine(item);
}
//在控制台中输出价格记录数
Console.WriteLine(“总计:” + count + “条记录”);
运行测试程序,控制台输出结果如图3所示。
孔夫子旧书网上对ISBN号为“9787302423287”的图书进行搜索的结果如图4所示。
由于搜索结果的显示页面过长,只截取页面局部,可以看到搜索结果的图书记录为78条,与测试结果一致。基于ScrapySharp的孔夫子旧书网的图书价格信息抓取器实现了预期的功能。
四、总结
ScrapySharp使用简单,使得.Net开发者更容易地解析Html文档,灵活地采集网页信息。应用此技术可以方便、高效地实现孔夫子旧书网的图书价格信息抓取器。测试结果表明,该软件的功能达到了预期效果。
参考文献:
[1]于娟,刘强.主题网络爬虫研究综述[J].计算机工程与科学,2015(02):231-237.
[2]孙立伟,何国辉,吴礼发.网络爬虫技术的研究[J].电脑知识与技术,2010(15):4112-4115.
[3]乔峰.基于模板化网络爬虫技术的Web网页信息抽取[M].电子科技大学,2015.
[4]肖剑.垂直搜索中一种高效稳定的数据抓取方法的研究与实现[M].南京大学,2014.