栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

py-02-爬虫比价器

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

py-02-爬虫比价器

py-02-爬虫比价器
目录: day01:用HttpClient+Jsoup的三种方式爬取网页内容 day02:抓取京东商品一系列信息(标题,卖点,价格,图片,描述) day03:京东、淘宝、苏宁、比价系统框架的搭建 day04:比价系统具体完善
day01 最终实现爬虫比价系统 苏宁,实现如果发现其他家商品比苏宁商品便宜,立刻降价。 软件系统,去各大网站爬取它们对应商品的价格,如果发现价格便宜,立刻修改自己的商品的价格。 技术难题: 如何解决去爬取其他商城的商品的信息,其中最重要价格! 爬虫项目中会涉及一些技术点
  1. Javascript , js ,脚本语言 python html/jsp

js规范它的代码都写在固定属性language=”javascript”

         

         js 只是在浏览器使用,功能受限,很多事情做不了(不能访问本地文件)           这种语言脚本语言。
  1. Json
就是一个字符串 ”{‘name’:’hello World’}” Json 本质是字符串,但是这个字符串有规定 字符串 {} ;有 key=name,value=hello World ;冒号分割 key:value http://p.3.cn/prices/mgets?skuIds=J_7348367 [ { "op":"899.00", "m":"9999.00", "id":"J_22769568633", "p":"899.00" } , { "op":"1699.00","m":"1999.00","id":"J_5842519","p":"1399.00" } ] []开始,支持多条记录,数组, 每条记录以{开始,以}结束,每条记录以逗号分隔 4个属性,key,value,多个属性以逗号隔开 3. Jsonp Fun(json) Showname(“{‘name’:’hello World’}”) Jsonp 本质就是一个函数名把一个 json 串括在里面 show([{"op":"899.00","m":"9999.00","id":"J_22769568633","p":"899.00"},{"op":"1699.00","m":"1999.00","id":"J_5842519","p":"1399.00"}]) http://d.3.cn/desc/7348367   4. ObjectMapper 转换工具     pojo 转成 json ; json 转成 pojo 5. HttpClient 最简单爬虫,爬取整个网站, Hadoop 底层 6. Jsoup 主角,专业爬虫; python beatifulsoup 7. Echarts 百度专业统计图形工具 网站获取有 3 种类型:
  1. html
  2. json ,本质字符串
  3. jsonp , fun(json) 本质还是字符串
追求:
  1. 对应目的,使用哪个工具更趁手
在工作中总会遇到新的知识,领导还不给你时间! 学会利用现有的程序,变成新的内容! 爬虫,学会爬京东,自己去学会爬淘宝。 创建一个 javaWeb 项目
  1. 导入 jar 包
commons-logging-1.1.1.jar                                   公用日志包,工具内部需要 httpclient-4.3.3.jar                                                httpClient 模拟 http 请求的客户端工具 httpcore-4.3.2.jar                                                   依赖包 jsoup-1.7.2.jar                                                         jsoup 爬虫包,爬虫工程师 jackson-annotations-2.4.0.jar                             jackson json      ObjectMapper 对象 pojo<>json jackson-core-2.4.2.jar jackson-databind-2.4.2.jar fastjson-1.1.37.jar 文件寻贴主要

抓取一个页面后

1.获取整个页面html 2.从中可以获取标题,内容,图片 可以做自己的新闻网站,今日头条都是自己的新闻吗?不是! 怎么从 Html 里分离出标题,内容,图片。 1.创建项目和导入jar包 1.1 用HttpClient的方式抓取  
package test;
import java.io.IOException;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.junit.Test;
public class TestHttpClient {

@Test
public void page() throws ClientProtocolException, IOException {
//目标:抓取整个网站


//                              客户端             习惯
HttpClientBuilder builder = HttpClients.custom();
HttpClient hc = builder.build();
//构建一个请求的对象
String url = "http://ent.qq.com/a/20180412/017735.htm";
HttpGet get = new HttpGet(url);
//执行完成把结果封装到响应的对象中,执行get请求
HttpResponse response = hc.execute(get);
//获取实体 返回对象
HttpEntity entity = response.getEntity();
//解析出整个页面的html代码;EntityUtils:实体工具对象
String html = EntityUtils.toString(entity);
System.out.println(html);
}
}
1.2 用Jsoup的方式抓取   标题 利用谷歌浏览器,快速定位标签,点击标签所在位置右键,检查 展现这个标签结构,如果只是部分内容,选择它的父标签,选中所有内容   工作中开发方式,无法把每个的内容都熟透! 应用!计算机是一门应用科学。 在别人的基础上实现新的功能。 HttpClient 模拟 http 请求,可以进行 代码 的提交。 问度娘, demo 做实例,那实例修改! 分析它的一个结构   抓取整个网站
  1. 网站页面中都有很多链接去链接别的页面
  2. 把页面中所有的 a 标签都抓取到,把它的链接在去抓
  3. 重复
  4. 别的网站,只抓本域名下的链接
  5. 要避免死循环,出现过的不抓了
抓取所有的 a 标签:
@Test      //抓取页面所有的a链接标签
public void a() throws IOException{
String url = "http://ent.qq.com/a/20171117/007399.htm";
Elements els = Jsoup.connect(url).get().select("a");
for(Element o:els){
System.out.println(o.attr("href"));
}
}
企业中实现一个爬虫秘诀:
  1. 要分析每个不同网站的不同的页面组成结构
  2. 反爬虫(电商)二次加载(有地方再次发出请求 url )
org.jsoup.UnsupportedMimeTypeException:
Unhandled content type. Must be text
@Test
public void html() throws IOException {
String url = "http://ent.qq.com/a/20180412/017735.htm";
//创建链接
Connection conn = Jsoup.connect(url);
//获取document页面对象
document docu = conn.get();
//获取页面的内容,jsoup中把网页中的所有body中的内容
Element ele = docu.body();
//获取到页面Html内容
String html = ele.html();
System.out.println(html);
}
@Test
public void titlel() throws IOException {
String url = "http://ent.qq.com/a/20180412/017735.htm";
//创建链接
Connection conn = Jsoup.connect(url);
//获取document页面对象
document docu = conn.get();
找到页面中所有的h1标签,放在一个元素集合
Elements ele = docu.select("h1");
//循环中每个元素类型 Elment,e给它起个别名,循环是每个对象,els就是上面的集合
for(Element e : ele) {
//获取其中的文本
String title = e.text();
System.out.println(title);
}

}
 
@Test
public void content() throws IOException {
String url = "http://ent.qq.com/a/20180412/017735.htm";
//创建链接
Connection conn = Jsoup.connect(url);
//获取document页面对象
document docu = conn.get();
找到页面中所有的h1标签,放在一个元素集合
Elements ele = docu.select(".bd");
for(Element e:ele) {
String content = e.text();
System.out.println(content);

}
}
@Test
public void img() throws IOException {
String url = "http://ent.qq.com/a/20180412/017735.htm";
Elements ele = Jsoup.connect(url).get().select("p img");
for(Element e:ele) {
String img = e.attr("src");
System.out.println(img);
}
}

@Test   
public void a() throws IOException{
String url = "http://ent.qq.com/a/20171117/007399.htm";
Elements els = Jsoup.connect(url).get().select("a");
for(Element o:els){
System.out.println(o.attr("href"));
}
}
------------------------------------------------------------------------------ 下午: 2.第二种抓取json串数据 1、创建TestJD类抓取京东商品的价格  
@Test
public void price() throws IOException {
String url = "http://p.3.cn/prices/mgets?skuIds=J_3296833";
//ignoreContentType:忽略内容类型
String json = Jsoup.connect(url).ignoreContentType(true).get().body().text();
System.out.println(json);

//2.获取json字符串中把p获取到

ObjectMapper om = new ObjectMapper();
//把字符串转成成JsonNode对象结构
JsonNode node = om.readTree(json);
//从JsonNode对象结构获取p
String price = node.get(0).get("p").asText();
System.out.println(price);//2999.00

}
2.第三种抓取jsonp数据  
@Test
public void deatil() throws IOException {
String url = "http://d.3.cn/desc/7348367";
String jsoup              =Jsoup.connect(url).ignoreContentType(true).get().body().text();
//截取字符串 showdesc({"date":
String json =jsoup.substring(9, jsoup.length()-1);
//获取Json串中的content属性的内容
ObjectMapper om = new ObjectMapper();
JsonNode node = om.readTree(json);
String desc =node.get("content").asText();
System.out.println(desc);

}


day02 知识回顾: 1.概念
Javascript 脚本语言(弱语言,只在网页使用,为了安全原因) java (面向对象,强语言)
Css 两种方式 style 属性; link 标签 base.css
Js 两种方式    xxx.js
Json 本质字符串, String a = “[{“name”:”[{},{}]”,”age”,18},{}]”;    成为日常系统交换数据的通用方式,安卓手机, httpclient+json
Jsonp 本质字符串, show([{},{}]) javascript 函数,解决跨域问题
ObjectMapper Jackson json 专门用于 pojo 和 json 字符串直接转换,从 json 字符串中挑出我们关心的属性的值
ObjectMapper MAPPER = new ObjectMapper();
//从json字符串中获取某个key的value?
JsonNode node = MAPPER.readTree(json);
//注意node中的结构,
数组:node.get(0).get(“p”).asText();
直接是单个元素:node.get(“p”).asText();
2.爬虫
Httpclient 模拟发起一个 http 请求,携带参数,获取返回值
Jsoup 真正爬虫,对页面数据有一套解析方法,利用 css ,样式表 +jQuery 提出选择器
选择器 3 种情况
  1. 直接使用 html 规范的标签: div
  2. 使用 id , #orderId
  3. 使用 class , .ordercss
  4. .select(.ordercss).select(.detail) 特殊情况
抓取一个 title 整个过程?
String url = “sina/1289392.htm”;
Connection cn = Jsoup.connect(url);         //找到要爬取的网站
Docment doc = cn.get();                             //获取到爬取的页面
Elements els = doc.select(“h1”);               //获取了h1标签的集合,集合只有一个元素
Element ele = els.get(0);                             //只获取第一个
for(Element e:els){                                        //获取多张图片
         e.attr(“src”);
}
ele.text();                                                                           //title文字
简洁方式:
Jsoup.connect(url).get().select(“h1”).get(0).text();

3.怎么在eclipse中调试代码(最多) 断点:breakpoint   在 debug 模式程序会自动进入到断点。   弹出的框是提示我们要进入新的 debug 的窗口环境,设置为 yes 。 以后不会弹出。         断点调试 3 个按钮,也支持快捷键 F5      进入到子程序中,调用一个函数,进入函数 F6      执行一行(用的最多) F7      跳出当前的执行,返回上级调用          Fun a(){                    Funb(); } 断点方便我们观察每个值, 时间开发中,大多数错误 99% ,变量的值不对; 通过断点观察这个值对不对! 4.抓取jd它的价格和描述怎么来的? 典型的二次提交         拷贝请求:

https://p.3.cn/prices/mgets?callback=jQuery634178&type=1&area=1_2901_4135_0.137859419&pdtk=&pduid=15196129033001458838393&pdpin=52399178_m&pin=52399178_m&pdbp=0&skuIds=J_4483112&ext=11000000&source=item-pc

http://p.3.cn/prices/mgets?skuIds=J_7348367

https:// 协议 http:// 安全,防止黑客攻击
/prices 映射路径
p.3.cn 网址 ,3.cn域名p.3.cn 二级域名
mgets 类似 servlet
? 参数的开始,很多的参数
& 参数之间分隔符
key,value
callback 参数名称
jQery334234 参数的值
  怎么去抓取jd商城的商品详情?
  1. 抓取核心信息:标题、卖点、价格、图片、描述
  2. 【华为荣耀10】荣耀10 GT游戏加速 AIS手持夜景 6GB+64GB 幻夜黑 全网通 移动联通电信4G 双卡双待 游戏手机【行情 报价 价格 评测】-京东
【香送抹茶半熟芝士(两只装)】香送 抹茶半熟芝士(两只装)【行情 报价 价格 评测】-京东

https:// 协议

item.jd.com二级域名

7348367  代表唯一标识id,

自增

解决方案:for 0(起始值小于网站商品的id值)到 99999999(大于最大的商品的id号)

Jsoup一个一个url抓

“京东(JD.COM)-正品低价、品质保障、配送及时、轻松购物!”+7348368+“.html”

缺点:很多链接无效的!

判断是否无效,判断时间很短,先必须出错,时间耗时!

从一级分类链接页面没规律,二级分类链接页面没规律, 都直接找不到很多 商品的链接。 三级分类,点开列表页面, 5*12=60 ,一页中显示 60 个商品 分页   找到列表页面,利用选择器找到当前页的所有的商品图片链接 Id 就可以找到,找到链接 jsoup ,抓取商品详情! https://list.jd.com/list.html?cat=9987,653,655# 【行情 价格 评价 正品行货】-京东,653,655&page=162 找到所有分页,再次请求,抓取到所有的页面的链接 这个方案中没有多余的 id ,都是真实的,抓取效率高! 总结: 目标:抓取所有商品的商品详情信息
  1. 只关注 3 级分类
  2. 获取分页总数
  3. 获取每一页数据
  4. 直接获取每个商品的详情
  5. 放到数据库(京东,淘宝,苏宁)比价系统
额外: 1.获取京东网站所有三级分类 网址选择步骤:

第一步:京东(JD.COM)-正品低价、品质保障、配送及时、轻松购物!

 

第二步:手机通讯频道

 

第三步:京东 - 全部分类

  京东 - 全部分类 aspx , .net ,后台服务都使用 java   创建项目-包-类   代码实现:
@Test
public void level3() throws IOException{
String url = "https://www.jd.com/allSort.aspx";
Elements els = Jsoup.connect(url).get()
.select(".items .clearfix dd a");
for(Element e:els){
//获取到商品的链接
String itemUrl = "http:"+e.attr("href");
//判断依据,有共同的前缀,以prefix前缀,true,false
if(itemUrl.startsWith("http://list.jd.com/list.html?cat=")){
System.out.println(itemUrl);
}
}
}

2.抓取某个分类分页总数,所有分页链接              手机 3 级分类, 161 页, 161*60 3.获取每一页数据   4.获取详情的链接    【行情 价格 评价 正品行货】-京东 ,653,655&page=1  
@Test
public void itemListUrl() throws IOException {

String url ="https://list.jd.com/list.html?cat=9987,653,655";
//获得总页数
Elements  ele = Jsoup.connect(url).get().select(".p-skip").select("b");
String pageAll=null;
for(Element e :ele) {
pageAll = e.text();
}
int page = Integer.parseInt(pageAll);
System.out.println(page);

//获得每一页的链接
String href = url+"&page=";
for(int i=1;i<=page;i++) {
String hrefs = href+i;
System.out.println(hrefs);
}
}
3.获取商品的链接

@Test
public void itemUrl() throws IOException{
String url = "https://list.jd.com/list.html?cat=9987,653,655&page=154";
Elements els = Jsoup.connect(url).get()
.select(".p-img a");
for(Element o:els){
String itemUrl = "http:"+o.attr("href");
System.out.println(itemUrl);
}
}
4.抓取所有商品的商品详情信息(标题,卖点,价格,图片,描述) 标题:  
@Test
public void getTitle() throws IOException {
String url ="https://item.jd.com/7348367.html";
String title =Jsoup.connect(url).get().select(".sku-name").get(0).text();
System.out.println("商品的标题是:"+title);
}
卖点: 查看数据:   得到: https://c.3.cn/recommend?callback=handleComboCallback&methods=accessories&sku=7348367&cat=9987%2C653%2C655
@Test
public void getSellPoint() throws IOException {
String url ="https://c.3.cn/recommend?callback=handle"+
"ComboCallback&methods=accessories&sku=73"+
"48367&cat=9987%2C653%2C655";
String jsoup = Jsoup.connect(url).ignoreContentType(true).execute().body();

String json =jsoup.substring(20, jsoup.length()-1);

System.out.println(json);
ObjectMapper om = new ObjectMapper();
JsonNode node = om.readTree(json);
String SellPoint =node.get("accessories").get("data").get("wName").asText();
System.out.println("卖点:"+SellPoint);
}
价格: 1.找到获取价格的请求可以看出是个jsoup的数据:   2.复制这条请求用谷歌浏览器筛选自己需要的数据得到 https://p.3.cn/prices/mgets?callback=jQuery1348823&type=1&skuIds=J_7348367   4.用火狐浏览器打开复制截取的链接确认数据类型:  
@Test
public void getPrice() throws IOException {
String url = "https://p.3.cn/prices/mgets?callback=jQuery1348823&type=1&skuIds=J_7348367";
//得到jsonp:
//jQuery1348823([{"op":"2599.00","m":"9999.00","id":"J_7348367","p":"2599.00"}]);
String jsonp =Jsoup.connect(url).ignoreContentType(true).execute().body();
System.out.println(jsonp);
//截取成json串
String json = jsonp.substring(14, jsonp.length()-3);
System.out.println(json);
ObjectMapper om = new ObjectMapper();
JsonNode node = om.readTree(json);
String price = node.get(0).get("op").asText();
System.out.println("价格:"+price);

}
图片  
@Test
public void getImage() throws IOException {
String url="https://item.jd.com/7348367.html";
Elements ele  = Jsoup.connect(url).get().select(".lh li img");

for(Element e:ele) {
String img = e.attr("src");
System.out.println(img);
}
}
描述  
@Test
public void getDesc() throws IOException {
String url = "https://item.jd.com/7348367.html";
Elements ele = Jsoup.connect(url).get().select(".p-parameter").select("ul").select("li");
//System.out.println(ele);
for(Element e : ele) {

System.out.println(e.text()+"n");
}
}
  1. 只关注 3 级分类 京东 - 全部分类 进入 【行情 价格 评价 正品行货】-京东 ,653,655
选择器 select ,它里面多个样式,必须嵌套关系 手机 手机 【行情 价格 评价 正品行货】-京东 数字内容 京东文娱-音乐频道 【行情 价格 评价 正品行货】-京东 ,794,798 爬虫爬取比较规范的数据,不规范的数据舍弃,如果需要这部分数据,单独写爬虫! 我们抓到三级分类 1259 个! 1183 有效! 5. 抓取商品详情,核心:                 标题                 卖点                 价格                 图片                 描述 小结: 抓取京东商品详情过程
  1. 获取京东商城的所有的三级页面,商品列表页面都是由三级页面点击而来
  2. 进入列表第一个页面,获取它的总页数,拼接成所有的访问页的链接
  3. 访问列表页面就获取到页面上的商品链接
  4. 一个一个属性抓取 a. 标题,直接抓网页定位

b. 卖点,二次请求,json

c. 价格,二次请求,json

d. 图片,只小图片,集合,直接抓取页面定位 e. 描述,二次请求, jsonp ,去掉函数就是 json 所有的 Json 引入 ObjectMapper 去搞定。 最难最耗时,二次请求和链接分析 反爬虫: A. 通过选择器来筛选,把 class 名称, id 改 B. 二次加载, json ,换个属性名, jsonp 换函数名
day03 知识回顾: 系统体验爬虫 爬取京东商城网站商品详情 开发步骤:
  1. 通过3级分类
  京东 - 全部分类 只有在 3 级分类下才会链接列表页面   一定要验证抓取结果是否正确,不正确,抓取的代码有问题,修改! 手机 手机 【行情 价格 评价 正品行货】-京东 数字内容 找共性,先把最多的统一链接形式的内容抓取下来,一般就足够了, 如果还不够,就像把电子书的抓取到?自己在写程序。 怎么找共性? 先把所有三级分类链接都打印出来,一扫一眼,就知道哪种更加标准或者说更多使用。 2 )所有的商品列表中有商品 id ,链接 手机 手机 【行情 价格 评价 正品行货】-京东 里面是含有分页,一页只能抓取 60 个数据, 手机 手机 【行情 价格 评价 正品行货】-京东 分析出来,其他的参数可以不要,只要 page 参数, page 就是当前页 拿到总页数,把它拼接成所有的分页链接,然后一个一个链接去抓取就可以 3 )获取到每页一个链接,获取商品详情 开始自己在页面中抓取各个展现数据。 a. 标题是可以直接抓取到 b. 利用直接抓取 price 价格,抓到空,观察,加载情况,标题人家是先出来的,短暂停留,价格才显现出来。直接就判断价格,二次提交,写入到它的位置。( ajax ) 找到二次提交的链接?       反爬虫,不会在链接中出现这种关键字 最差一个情况:一个一个链接找 它隐藏,有时隐藏 js 、 没思路,百度,找前人的经验! c. 卖点 http://ad.3.cn/ads/mgets?skuids=AD_1411013,AD_1411014 百度获取的链接,从前人经验中获取这个信息 d. 图片 直接在网页,直接能抓取小图片 e. 描述 http://d.3.cn/desc/1411013 在 f12 调试时,过滤查询到,也可以获取前人的经验 抓取一个新网站时两种方式
  1. 自己分析
  2. 获取前人的经验(百度)
豆瓣(毕业设计) 电影,评分,评论
  1. 电影推荐
  2. 电影海报 quartz 定时器,每天一张海报
  3. 评分可以写成排行,每月一个电影排行榜
  4. 评论
统计图表
  1. 饼形图
换成:个人消费的饼形图 要求:
  1. 3 个,生活中的分类;住宿,旅游,学习
  2. 5 个,住宿,旅游,学习,吃饭,交女盆友
     

2. 柱状图
  1. 3 个, 3 次月考成绩
  2. 5 个指标,语文 99 ,数学 100 ,英语 60 ,化学 5 ,物理 10

3. 曲线图
  1. 一周早晨到校时间
  2. 工作日 5 天离校时间
工作中解决问题: 以工程思路去做! 最终项目目标: 需求:   抓取京东、淘宝、苏宁三家电商,某个商品的价格,用 echarts 百度图表软件展现出来,领导一看非常直观,领导来决定是否降价。 关键技术点:
  1. 抓取京东商城的某个商品的价格? a. 确定某个商品,(动态抓)
  2. 如何抓取淘宝、苏宁?
  3. 如何最终在 echarts 页面上展现出来
隐藏一个问题:怎么判断是同一个商品? 商品有不同规格和颜色,怎么能断定它是同一个呢? 技巧: 思路:(一个,动态) 利用搜索条,假设输入条件足够详细,理论上查询出来的商品信息匹配度越高。可以近似认为它们是等同。 来抓取列表的第一个商品的信息,价格信息,然后把 3 个商城的价格信息 传递给 jsp 页面,形成 echarts 所要的数据结构。 最终形成柱状图。 扩展:(批量,事先抓好)
  1. 都抓到数据库
  2. 列出多个字段,
  3. 做一个判断,京东 - 苏宁 <0 ,修改价格,淘宝 - 苏宁 <0 ,
京东 - 商品搜索 - 京东 iphonex%2064g iphonex 64g_iphonex 64g推荐 - 苏宁易购 天猫tmall.com--理想生活上天猫 开发步骤:
  1. 搜索 url 都有找到,动态拼接上搜索关键字
  2. Servlet+ 创建 jsp 文件,输入框,用户可以填写关键字(表单)
SearchServlet , search.jsp

 3. 提交submit,转向到另外servlet,利用jsoup分别抓各个商场搜索数据,近似值,抓取第一款商品id

写成 3 个方法 getJDPrice          抓取京东商城某个商品的价格 getTBPrice          抓取淘宝商城某个商品的价格 getSNPrice          抓取苏宁商城某个商品的价格

 4. 通过商品详情链接,拼接上id,找到商品链接地址

 5. 只抓取价格

 6. 3个价格都抓取到拼接成满足echarts要的字符串结构,把字符串request传递给统计jsp页面

DoServlet 调用每个方法,获取其价格,然后拼接 jsp 页面所要字符串 写入 request 对象中

 7. 统计的Jsp页面通过el表达式获取数据,最终以柱状图展现

result.jsp 实际开发中,
  1. 先搭建框架,其中遇到方法,假装! getPrice return 100;
  2. 每个小细节最终不同的人员完成,团队开发。
  在页面中请求分成 2 类, 一类 get 请求, iphonex - 商品搜索 - 京东 %20 64g %2 0 黑色 一类 post 请求(表单请求就属于)
知识回顾: 系统体验爬虫 爬取京东商城网站商品详情 开发步骤:
  1. 通过 3 级分类
  京东 - 全部分类 只有在 3 级分类下才会链接列表页面   一定要验证抓取结果是否正确,不正确,抓取的代码有问题,修改! 手机 手机 【行情 价格 评价 正品行货】-京东 数字内容 找共性,先把最多的统一链接形式的内容抓取下来,一般就足够了, 如果还不够,就像把电子书的抓取到?自己在写程序。 怎么找共性? 先把所有三级分类链接都打印出来,一扫一眼,就知道哪种更加标准或者说更多使用。 2 )所有的商品列表中有商品 id ,链接 手机 手机 【行情 价格 评价 正品行货】-京东 里面是含有分页,一页只能抓取 60 个数据, 手机 手机 【行情 价格 评价 正品行货】-京东 分析出来,其他的参数可以不要,只要 page 参数, page 就是当前页 拿到总页数,把它拼接成所有的分页链接,然后一个一个链接去抓取就可以 3 )获取到每页一个链接,获取商品详情 开始自己在页面中抓取各个展现数据。 a. 标题是可以直接抓取到 b. 利用直接抓取 price 价格,抓到空,观察,加载情况,标题人家是先出来的,短暂停留,价格才显现出来。直接就判断价格,二次提交,写入到它的位置。( ajax ) 找到二次提交的链接?       反爬虫,不会在链接中出现这种关键字 最差一个情况:一个一个链接找 它隐藏,有时隐藏 js 、 没思路,百度,找前人的经验! c. 卖点 http://ad.3.cn/ads/mgets?skuids=AD_1411013,AD_1411014 百度获取的链接,从前人经验中获取这个信息 d. 图片 直接在网页,直接能抓取小图片 e. 描述 http://d.3.cn/desc/1411013 在 f12 调试时,过滤查询到,也可以获取前人的经验 抓取一个新网站时两种方式
  1. 自己分析
  2. 获取前人的经验(百度)
豆瓣(毕业设计) 电影,评分,评论
  1. 电影推荐
  2. 电影海报 quartz 定时器,每天一张海报
  3. 评分可以写成排行,每月一个电影排行榜
  4. 评论
统计图表
  1. 饼形图
换成:个人消费的饼形图 要求:
  1. 3 个,生活中的分类;住宿,旅游,学习
  2. 5 个,住宿,旅游,学习,吃饭,交女盆友
     

 2. 柱状图

  1. 3 个, 3 次月考成绩
  2. 5 个指标,语文 99 ,数学 100 ,英语 60 ,化学 5 ,物理 10

 3.曲线图

  1. 一周早晨到校时间
  2. 工作日 5 天离校时间
工作中解决问题: 以工程思路去做! 最终项目目标: 需求:   抓取京东、淘宝、苏宁三家电商,某个商品的价格,用 echarts 百度图表软件展现出来,领导一看非常直观,领导来决定是否降价。 关键技术点:
  1. 抓取京东商城的某个商品的价格? a. 确定某个商品,(动态抓)
  2. 如何抓取淘宝、苏宁?
  3. 如何最终在 echarts 页面上展现出来
隐藏一个问题:怎么判断是同一个商品? 商品有不同规格和颜色,怎么能断定它是同一个呢? 技巧: 思路:(一个,动态) 利用搜索条,假设输入条件足够详细,理论上查询出来的商品信息匹配度越高。可以近似认为它们是等同。 来抓取列表的第一个商品的信息,价格信息,然后把 3 个商城的价格信息 传递给 jsp 页面,形成 echarts 所要的数据结构。 最终形成柱状图。 扩展:(批量,事先抓好)
  1. 都抓到数据库
  2. 列出多个字段,
  3. 做一个判断,京东 - 苏宁 <0 ,修改价格,淘宝 - 苏宁 <0 ,
京东 - 商品搜索 - 京东 iphonex%2064g iphonex 64g_iphonex 64g推荐 - 苏宁易购 天猫tmall.com--理想生活上天猫 开发步骤:
  1. 搜索 url 都有找到,动态拼接上搜索关键字
  2. Servlet+ 创建 jsp 文件,输入框,用户可以填写关键字(表单)
SearchServlet , search.jsp

 3. 提交submit,转向到另外servlet,利用jsoup分别抓各个商场搜索数据,近似值,抓取第一款商品id

写成 3 个方法 getJDPrice          抓取京东商城某个商品的价格 getTBPrice          抓取淘宝商城某个商品的价格 getSNPrice          抓取苏宁商城某个商品的价格

 4. 通过商品详情链接,拼接上id,找到商品链接地址

 5. 只抓取价格

 6. 3个价格都抓取到拼接成满足echarts要的字符串结构,把字符串request传递给统计jsp页面

DoServlet 调用每个方法,获取其价格,然后拼接 jsp 页面所要字符串 写入 request 对象中

 7. 统计的Jsp页面通过el表达式获取数据,最终以柱状图展现

result.jsp 实际开发中,
  1. 先搭建框架,其中遇到方法,假装! getPrice return 100;
  2. 每个小细节最终不同的人员完成,团队开发。
  在页面中请求分成 2 类, 一类 get 请求, iphonex - 商品搜索 - 京东 %20 64g %2 0 黑色 一类 post 请求(表单请求就属于)
day04 知识回顾:
  1. 画图
拿到项目,任务,无从下手。 a. 分解任务,把一个大任务分成很多的小的任务,然后去实现每个任务,链接起来就实现最终大任务。开发步骤。 b. 画图,一图百文。流程图。整个完成爬虫过程。先把框架性画出来,然后一个一个点去实现,最终项目也就完成。

 2. 系统框架图,系统的架构图

Servlet,jsp,jsoup           任务:爬取京东、淘宝、苏宁;动态实现输入关键字,我们的系统后台分别去每个网站抓取价格,最终返回后拼接成字符串,最终通过 echarts 柱状图展现。   今天内容:
  1. 从头把整个项目实现
开发步骤:

     a. 创建javaWeb,配置tomcat,把项目部署上去

     b. 搭建项目框架,然后在细化每个内容

创建类: SearchServlet , DoServlet 创建安全的访问的 jsp 路径 /WEB-INF/views 创建两个空的 jsp : search.jsp , result.jsp

    c. 细化

SearchServlet 直接转向 search.jsp search.jsp 创建 , 创建一个输入框 , 创建一个提交按钮 (提交按钮的价值在于用户点击后自动去执行 form.action 链接) DoServlet 获取参数 request.getParameter(“key”) ,转换中文 调用 3 个网站爬虫方法,京东 jsoup ,苏宁 jsoup ,淘宝 jsoup+httpclient resuslt.jsp 接收 DoServlet 参数,标识一个价格字符串,直接用 el 表达式嵌入到 json Jsp 因为语法校验,如果出错,出错提示,看看是否是自己写错。 不管它了,在页面运行起来是进行检查! Class 报错,预编译错误,当文件保存, eclipse 进行编译。如果报错说明没有编译过去。基本是运行不了的,这种错误必须解决。 2. 把项目进行优化(重构) 爬虫遇到新的内容
  1. 反爬虫技术,如果是当前网站转过来的链接就可以继续的访问,如果不是就直接拒绝
403 Forbidden 淘宝为了链接的安全,防止盗链,或者从其他的网站来提交这个链接 检查域名 taobao.com, 解决方案: 自己设置一个请求头, Referer 代表当前页是从哪个页面过来的( html 规范)

 2.反爬虫,每个请求都会有一个请求头来标识自己是谁,规范。请求头中就会标识我是火狐,就会标识我是一个谷歌浏览器,如果httpclient它也有自己的标识,jsoup它也有自己的标识。

服务器后台可以获取这个信息,判断如果是浏览器就可以执行,如果不是也就说明是爬虫类型,服务器就会拒绝 解决方案: 伪装请求头      

 3. 反爬虫,服务器会获取到所有用户的请求,例如tomcat就可以,它会把所有的信息写入到日志文件,监控这个日志文件,就能发现在很短时间内某一个ip地址频繁的访问,1s几百次以上。Nginx监控,封杀。害怕封杀错误,把这个ip暂时加入到一个黑名单中,1分钟后释放。

解决方案: a. 动态 ip ,花生壳(不是很好用) b. 简单易行,延时。延时 1 分钟,黑名单 1 小时,抓取效率极低。 小结:
  1. 爬虫,几种方式 httpclient,jsoup 。
  2. httpClient 模拟浏览器发起 http 请求,请求和响应 response , api ( application interface 应用程序接口)把 httpClient 工具包。 Api 学习成本高
  3. jsoup java soup , java 爬虫,引入选择器 select ,选择器利用 tag ( div span h1 a img ) ,id (页面唯一性, #id ) ,class 属性( style 样式修饰用,定位,重复几率很大, .class )
  4. 获取 json 中某个节点的数据
ObjectMapper MAPPER = new ObjectMapper(); JsonNode node = MAPPER.readTree(json 字符串 ) ; 数组 for ( JsonNode n :node ) {  n.get(“name”); } node.get(0); 文本 node.get(“name”).asText(); 获取它的 href 属性: node.get(0).get(“name”).attr(“href”);

 5. Servlet3.0 ,(2.3 需要一个配置文件去声明servlet)通过@WebServlet注解方式

 6. Request请求对象,封装jsp页面的请求参数,request.getParamter

 7. 转向request.getRequestDispatcher(“result.jsp”).forword(request,response);

 8. Jsp引入样式表

 9. Jsp引入taglib <%@ taglib prefix=”c” uri=” Oracle Java Technologies | Oracle”>

<%@ taglib prefix=”fmt” uri=” Oracle Java Technologies | Oracle ”> 格式化日期

 10. Jstl进行for循环

 ${o.name}

 11. EL表达式${name}

 12. Json [{“name”:”tony”},{}] 中括号数组,大括号一条记录,字符串使用双引号括起来,之间用逗号分库

 13. Jsonp fun(json),去掉函数名,剩下就是json,通过ObjectMapper

 14.