爱立信俱乐部给小朋友练手的一个小插件
需求文件下载 这里
Chrome 扩展入门
由于本次需求是一款在淘宝和天猫使用的查询评论插件,360安全浏览器和极速浏览器好像都是以chromium为内核的,故在此直接开发Chrome扩展。
这里要非常感谢360把Chrome扩展的开发文档翻译了,传送门
创建并加载一个应用
1.在本地磁盘新建一个目录,之后所有的资源文件都会放在里面。
2.在该目录底下创建一个名称为manifest.json的文本文件。
接下来我们创建一个HelloWorld扩展程序
首先新建一个文件夹,我们取名为helloworld,然后在文件夹内新建一个manifest.json文件和一个popup.html文件
在manifest.json文件内填入以下内容:
1 | { |
在popup.html文件内填入以下内容:(其实就是一个任意的html
1 |
|
打开Chrome,在地址栏中输入chrome://extensions/
进入扩展程序页面,
勾上开发者模式,然后点击加载已解压的扩展程序,在弹出的框中选择我们刚才新建的文件夹(我们创建的json文件和html文件在里面)
加载成功后,可以在右上角看到我们的新扩展应用的图标,按下后会弹出刚才我们创建的html文件渲染后的样子。
helloworld 应用结束
根据教程以及该插件的需求,我的manifest.json文件设置为如下
1 | { |
name,version,description大家都清楚,
然后manifest_version是官方要求填写2
browser_action是在点击插件图标时的相应,设置了popup就会弹出一个小框框
比如这样
permissions是指插件的权限,这里我填写了淘宝和天猫的网址,用于获取权限来爬去评论数据。还有tab是读取浏览器标签的权限,加上百度的网址的缘由我后面再说。
background填写在此处的脚本会在浏览器打开之后就在后台运行,如果需要一直在后台静默运行,把脚本添加至此处即可。
content_scripts是我们的重头戏。
因为需求是需要在鼠标移到图片上就即时爬取信息,我们需要时刻关注鼠标的位置,这就需要content_script。
Content scripts是在Web页面内运行的javascript脚本。通过使用标准的DOM,它们可以获取浏览器所访问页面的详细信息,并可以修改这些信息。
我在这里填写了
"matches": ["https://s.taobao.com/*"]
是当用户在淘宝搜索的时候,该脚本才会激活。
在构建页面的组件的时候,我采用了体积微小的Google官方出品的Material Design组件 - material-design-lite.
使用的时候只要includematerial.min.css
和material.min.js
两个文件即可。
至于run_at是指这个脚本加载的时机,如果是document_idle,浏览器会在document_end和发出window.onload事件之间的某个时机注入。具体的时机取决与文档加载的复杂度,为加快页面加载而优化。
本次我们的代码集中在main.js这个文件里面。
构建弹窗
通过查看在淘宝搜索物品的页面,要捕捉用户鼠标移到图片上面的话,主要是有两个方法
1.时刻检测鼠标的坐标。
2.对每个需要监听的位置添加一个事件,通过事件触发。
由于不同窗口大小,坐标位置也不一样,不好判定,我采用了第二个方法。
通过观察该页面的DOM结构,查找出了每一个商品图片的特点
先用class定位到每一个商品div,再对每一个div里面的图片img标签添加onmouseenter事件。
1 | var items = $('.pic-link.J_ClickStat.J_ItemPicA[data-href]'); |
随后发现,筛选出来的只有36个商品,然而当我们往下滚动的时候,会陆续获取更多的商品,当我滚动页面到底部的时候,出现了48个商品,然后在我们刚打开页面的时候,只有36个,这样如果我在页面刚出来就添加事件监听的话,会遗漏还没有加载的12个商品,这个问题暂时先忽略。
以及直接遍历筛选结果还会有length和prevObject等元素,故判断了是否是数字isNaN().
接下来,当鼠标移动到图片的时候,会触发popup函数,我们将在popup函数中创建一个长条框,并显示评论内容。
在popup函数中我把this作为参数传进去了,主要是用于获得该商品div里面的href这个属性的内容,因为这个是后面用来获取itemID和sellerID的地方。
按照面向对象的思想,我创建了一个类FloatingFrame.由于没有必要重复创建和删除同一个框框,我的想法是一开始就创建好这个框框并隐藏,每次事件触发时,移动到目标位置并解除隐藏,关闭的时候再次隐藏,同时使用单例模式来更好的管理这个长条框。
爬取天猫的评论
在寻找需要爬取的内容时,我们使用地表最强浏览器Chrome的强大的开发者工具。
我打开了一个刚才搜索列表中的一个天猫商品的页面,找到评论的位置,使用Chrome的开发者工具,清空Network里面的内容
然后点击图片这个Radio Button之后,查看NetWork的记录,可以清楚的看到第一条记录
查看返回的内容可以看到,这正是我们需要的评论记录!
继续展开这个JSON数组,更加确信了!
那么,我们要如何获取这个数据呢,查看这个网络记录的header
根据这些记录,我们就可以发送同样的请求,获取评论信息,然后进行页面渲染到我们创建的长条框中.
这个请求中必须的参数是URL以及若干个Query String Parameters
由图中可以看到,该请求的URL是https://rate.tmall.com/list_detail_rate.htm
而几个请求参数中,itemID和SellerID是查询的关键,经过我自己私下的测试,发现spuID和ua这两个参数好像无关紧要,于是我舍弃了,还有经过和查看’追评’评论的请求对比,发现这两个请求的URL和大部分参数都一样,只有append和picture这两个参数不一样,所以获取天猫的图片评论和追评评论的方法可以写成同一套,然后只要区分这两个参数即可。
我写的爬取方法如下
1 | getCommentDataFromTmall(type) { |
可以看到这里嵌套了两个Ajax请求,第一个是获取itemID和sellerID的请求,在获得这两个参数之后,才真正地往刚才我们查询到的URL发送新的请求获取评论内容。
在提取itemID和sellerID时,我先在搜索页面获取到鼠标指向的商品,在触发的popup函数中我从this参数中可以获得href链接,通过这个链接发送Ajax请求获得返回结果之后,采用正则表达式过滤,以上代码中使用的两个正则表达式如下
1 | this.tmall_itemId_reg = new RegExp("itemId:\"[0,1,2,3,4,5,6,7,8,9]*\""); |
爬取淘宝的评论
按照和爬取天猫评论同样的思路,爬取淘宝的评论没啥问题,这里不再赘述。
关于’问大家’
当我尝试爬取问大家的内容时,发现请求需要一个Appkey的参数和一个t参数以及一个sign签名参数,不能缺少,却不通用,似乎是随机生成的,而且每次生成的还有时间限制。在这些障碍下,我暂时放弃了这个爬取。
一些问题
现在这个小demo存在两个大问题是
1.搜索结果的第一个商品是无法查询的,因为第一个商品的链接是需要经过一个跳转才能达到目标网页的,本人太懒于是先忽略了。
2.另一个是往下滚动时或者翻页之后,后续加载的商品不能监听到鼠标hover的事件。
源代码的使用
打开chrome的扩展程序页面,勾上开发者模式,点击加载已解压的扩展程序,选中源代码所在的目录即可。
扩展包的安装
将crz后缀的安装包拖入Chrome扩展程序页面即可。
源代码可以在这里下载到
extension-shop-sourcecode.rar
终于更了一篇博文:)