基于ScrapySharp的孔夫子旧书网的图书价格信息抓取器的实现

2017-10-21 00:15李金峰郭冰李金隆
科技信息·中旬刊 2017年7期

李金峰 郭冰 李金隆

摘要: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 GetKongfuziPriceByIsbn(string isbn)

{

try

{

//价格信息集合

List priceStrList = new 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 priceStrList = helper.GetKongfuziPriceByIsbn(“9787302423287”);

//价格记录数

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.