精华内容
下载资源
问答
  • Java实现网络爬虫:爬取京东商品案例
    2020-07-12 16:23:36

    爬取京东商品案例

    需求分析

    一、需求
    抓取京东商城的数据,把商品数据保存到数据库。

    二、功能分析

    1. 使用HttpClient发送一个get请求,请求搜索url,得到商品列表
    2. 使用jsoup解析搜索结果页面。
    3. 把商品信息封装一个对象中。
    4. 把商品数据保存到数据库。

    三、京东页面分析
    当在京东的搜索框输入手机时,此时的url为

    https://search.jd.com/Search?keyword=手机&wq=手机&page=1&s=1&click=1
    

    当进行翻页操作,发现page值为1,3,5,7…进一步分析发现,京东商品每一页展示两页数据,当看完一页数据后,拉到底部,会显示第二页数据,当看完第二页数据,才会进行翻页操作,此时真正进入第二页。

    问题:京东商城每次只展示30条数据,后30条数据(每页的第二页)是ajax动态加载的,使用HttpClient解决非常麻烦,此处不进行爬取后30条数据。

    爬取页数:取10页数据。

    爬取的信息:商品标题,价格,图片,skuid,spuid,商品详情地址等
    在这里插入图片描述
    在这里插入图片描述

    四、数据库表创建

    保存到数据库:创建一个数据库。需要的字段都是商品列表中可以解析出来的字段。

    CREATE TABLE `jd_item` (
      `id` bigint(10) NOT NULL AUTO_INCREMENT COMMENT '主键id',
      `spu` bigint(15) DEFAULT NULL COMMENT '商品集合id',
      `sku` bigint(15) DEFAULT NULL COMMENT '商品最小品类单元id',
      `title` varchar(1000) DEFAULT NULL COMMENT '商品标题',
      `price` float(10,0) DEFAULT NULL COMMENT '商品价格',
      `pic` varchar(200) DEFAULT NULL COMMENT '商品图片',
      `url` varchar(1500) DEFAULT NULL COMMENT '商品详情地址',
      `created` datetime DEFAULT NULL COMMENT '创建时间',
      `updated` datetime DEFAULT NULL COMMENT '更新时间',
      PRIMARY KEY (`id`),
      KEY `sku` (`sku`) USING BTREE
    ) ENGINE=InnoDB AUTO_INCREMENT=217 DEFAULT CHARSET=utf8 COMMENT='京东商品';
    

    代码实现

    编写爬虫的业务逻辑
    1、使用工具类创建一个HttpClient对象。
    2、使用HttpClient发送请求,请求就是搜索的url+页码
    3、接收服务端响应html
    4、使用Jsoup解析html
    5、把解析的商品数据封装成Item对象
    6、使用dao把商品写入数据库。
    7、需要翻页。

    注意:图片也是一个http请求,需要再次发起请求爬取图片,然后存储到本地

    @Component
    public class Crawler {
    
        @Autowired
        private ItemDao itemDao;
    
        private String startUrl = "https://search.jd.com/Search?keyword=手机&wq=手机&s=1&click=1&page=";
    
        /**
         * 爬取页面
         */
        public void doCrawler() {
            try {
                //1、使用工具类创建一个HttpClient对象。
                CloseableHttpClient httpClient = HttpsUtils.getHttpClient();
                for (int i = 0; i < 10; i++) {
                    //2、使用HttpClient发送请求,请求就是搜索的url+页码
                    HttpGet get = new HttpGet(startUrl + (i * 2 + 1));
                    get.addHeader("User-Agent", " Mozilla/5.0 (Windows NT 6.1; WOW64; rv:64.0) Gecko/20100101 Firefox/64.0");
                    CloseableHttpResponse response = httpClient.execute(get);
                    //3、接收服务端响应html
                    HttpEntity entity = response.getEntity();
                    String html = EntityUtils.toString(entity, "utf-8");
                    //4、使用Jsoup解析html
                    parseHtml(html);
                    //5、把解析的商品数据封装成Item对象
                    //6、使用dao把商品写入数据库。
                    //7、需要翻页。
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        /**
         * 页面解析
         * @param html
         */
        private void parseHtml(String html) throws Exception {
            //4、使用Jsoup解析html
            Document document = Jsoup.parse(html);
            //解析商品列表
            Elements elements = document.select("li.gl-item");
            for (Element element : elements) {
                //解析节点中的商品数据
                //spu
                String spu = element.attr("data-spu");
                //sku
                String sku = element.attr("data-sku");
                //title
                String title = element.select("div.p-name em").text();
                //price
                String price = element.select("div.p-price i").text();
                //图片
                String imgUrl = element.select("div.p-img img").attr("src");
                String imageName = downloadImage(imgUrl);
                //商品的url
                String itemUrl = element.select("div.p-img > a").attr("href");
                //5、把解析的商品数据封装成Item对象
                Item item = new Item();
                item.setSpu(Long.parseLong(spu));
                item.setSku(Long.parseLong(sku));
                item.setTitle(title);
                if (StringUtils.isNotBlank(price)) {
                    item.setPrice(Float.parseFloat(price));
                }
                item.setPic(imageName);
                item.setUrl(itemUrl);
                item.setCreated(new Date());
                item.setUpdated(new Date());
                //6、使用dao把商品写入数据库。
                itemDao.save(item);
            }
        }
    
        /**
         * 爬取图片
         * @param imageUrl
         * @return
         */
        private String downloadImage(String imageUrl) throws Exception {
            //创建一个HttpClient对象
            CloseableHttpClient httpClient = HttpsUtils.getHttpClient();
            //创建一个HttpGet对象
            HttpGet get = new HttpGet("https:" + imageUrl);
            get.addHeader("User-Agent", " Mozilla/5.0 (Windows NT 6.1; WOW64; rv:64.0) Gecko/20100101 Firefox/64.0");
            //发送请求
            CloseableHttpResponse response = httpClient.execute(get);
            //接收服务端响应的内容。
            HttpEntity entity = response.getEntity();
            //需要截取扩展名
            String extName = imageUrl.substring(imageUrl.lastIndexOf("."));
            //需要生成文件名。可以使用uuid生成文件名。
            String fileName = UUID.randomUUID() + extName;
            //D:\temp\term331\images
            //创建一个文件输出流,把文件保存到磁盘
            FileOutputStream outputStream = new FileOutputStream("D:\\temp\\images\\" + fileName);
            //接收流,把内容保存到磁盘。
            entity.writeTo(outputStream);
            //关闭流
            outputStream.close();
            //关闭Response对象
            response.close();
            return fileName;
        }
    }
    
    

    开启新线程可以让爬取在后台进行,而不是页面一直在转

    @RestController
    public class CrawlerController {
        @Autowired
        private Crawler crawler;
    
        @RequestMapping("/start")
        public String startCrawler() {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println("新线程已经启动。。。。。");
                    crawler.doCrawler();
    
                }
            }).start();
            return "OK";
        }
    }
    
    更多相关内容
  • java爬虫 京东商品页 简单案例

    千次阅读 热门讨论 2016-04-30 13:41:26
    java爬虫 HttpClient HtmlCleaner Xpath mysql 京东
    HttpClient + htmlcleaner + xpath  + MySQL      Java语言
    要爬的数据



    数据库表结构

    数据库建表语句
    SET FOREIGN_KEY_CHECKS=0;
    
    -- ----------------------------
    -- Table structure for `spider`
    -- ----------------------------
    DROP TABLE IF EXISTS `spider`;
    CREATE TABLE `spider` (
      `id` int(10) NOT NULL AUTO_INCREMENT,
      `goods_id` varchar(20) DEFAULT NULL,
      `data_url` varchar(300) DEFAULT NULL,
      `pic_url` varchar(300) DEFAULT NULL,
      `title` varchar(300) DEFAULT NULL,
      `price` varchar(10) DEFAULT NULL,
      `param` text,
      `current_time` datetime DEFAULT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8;

    项目的包结构


    pom.xml 文件中的jar包依赖
    <dependencies>
    	        <dependency>
    			<groupId>junit</groupId>
    			<artifactId>junit</artifactId>
    			<version>4.12</version>
    			<scope>test</scope>
    		</dependency>
    		<dependency>
    			<groupId>org.apache.httpcomponents</groupId>
    			<artifactId>httpclient</artifactId>
    			<version>4.4</version>
    		</dependency>
    		<dependency>
    			<groupId>net.sourceforge.htmlcleaner</groupId>
    			<artifactId>htmlcleaner</artifactId>
    			<version>2.16</version>
    		</dependency>
    		<dependency>
    			<groupId>org.json</groupId>
    			<artifactId>json</artifactId>
    			<version>20160212</version>
    		</dependency>
    		<dependency>
    			<groupId>mysql</groupId>
    			<artifactId>mysql-connector-java</artifactId>
    			<version>5.1.38</version>
    		</dependency>
    		<dependency>
    			<groupId>commons-dbutils</groupId>
    			<artifactId>commons-dbutils</artifactId>
    			<version>1.6</version>
    		</dependency>
    </dependencies>

    编写实体类
    import java.util.HashMap;
    import java.util.Map;
    
    /**
     * 页面实体类
     * 保存页面信息
     */
    public class Page {
    
    	private String goodId;// 商品ID
    	private String goodName;//商品名称
    	private String dataUrl;//商品URL地址
    	private String picUrl;//商品图片URL地址
    	private String price;//价格
    	private Map<String, String> param = new HashMap<String, String>();//商品参数规格
    	private String content;//页面原始源代码内容
    	
    	public String getGoodId() {
    		return goodId;
    	}
    	public void setGoodId(String goodId) {
    		this.goodId = goodId;
    	}
    	public String getGoodName() {
    		return goodName;
    	}
    	public void setGoodName(String goodName) {
    		this.goodName = goodName;
    	}
    	public String getDataUrl() {
    		return dataUrl;
    	}
    	public void setDataUrl(String dataUrl) {
    		this.dataUrl = dataUrl;
    	}
    	public Map<String, String> getParam() {
    		return param;
    	}
    	public void setParam(String key,String value) {
    		this.param.put(key, value);
    	}
    	public String getContent() {
    		return content;
    	}
    	public void setContent(String content) {
    		this.content = content;
    	}
    	public String getPicUrl() {
    		return picUrl;
    	}
    	public void setPicUrl(String picUrl) {
    		this.picUrl = picUrl;
    	}
    	public String getPrice() {
    		return price;
    	}
    	public void setPrice(String price) {
    		this.price = price;
    	}
    }

    spider类
    import cn.crxy.maven.Spider.domain.Page;
    import cn.crxy.maven.Spider.download.Downloadable;
    import cn.crxy.maven.Spider.process.Processable;
    import cn.crxy.maven.Spider.store.Storeable;
    
    public class Spider {
    
    	private Downloadable downloadable;
    	private Processable processable;
    	private Storeable storeable;
    	
    	//下载页面源代码
    	public Page download(String url){
    		return downloadable.download(url);
    	}
    	
    	//解析页面源代码
    	public void process(Page page){
    		processable.process(page);
    	}
    	
    	 //将解析后的数据保存到数据库 
    	public void store(Page page){
    		storeable.store(page);
    	}
    
    	public Downloadable getDownloadable() {
    		return downloadable;
    	}
    
    	public void setDownloadable(Downloadable downloadable) {
    		this.downloadable = downloadable;
    	}
    
    	public Processable getProcessable() {
    		return processable;
    	}
    
    	public void setProcessable(Processable processable) {
    		this.processable = processable;
    	}
    
    	public Storeable getStoreable() {
    		return storeable;
    	}
    
    	public void setStoreable(Storeable storeable) {
    		this.storeable = storeable;
    	}
    }

    Downloadable接口类
    import cn.crxy.maven.Spider.domain.Page;
    
    public interface Downloadable {
    	Page download(String url);
    }

    DownloadImpl实现类
    import cn.crxy.maven.Spider.domain.Page;
    import cn.crxy.maven.Spider.utils.PageUtil;
    
    public class DownloadImpl implements Downloadable {
    	
    	public Page download(String url) {
    		Page page = new Page();
    		String content=PageUtil.getContent(url);//根据url得到内容
    		page.setContent(content);
    		page.setDataUrl(url);
    		return page;
    	}
    }

    PageUtil页面工具类
    import java.io.IOException;
    
    import org.apache.http.HttpEntity;
    import org.apache.http.client.ClientProtocolException;
    import org.apache.http.client.methods.CloseableHttpResponse;
    import org.apache.http.client.methods.HttpGet;
    import org.apache.http.impl.client.CloseableHttpClient;
    import org.apache.http.impl.client.HttpClientBuilder;
    import org.apache.http.impl.client.HttpClients;
    import org.apache.http.util.EntityUtils;
    
    /**
     * 根据URL获取url对应的内容
     */
    public class PageUtil {
    
    	public static String getContent(String url){
    		HttpClientBuilder custom = HttpClients.custom();//创建httpclient
    		//通过构建器构建一个httpclient对象,可以认为是获取到一个浏览器对象
    		CloseableHttpClient build = custom.build();
    		//把url封装到get请求中
    		HttpGet httpGet = new HttpGet(url);
    		String content = null;
    		try {
    			//使用client执行get请求,获取请求的结果,请求的结果被封装到response中
    			CloseableHttpResponse response = build.execute(httpGet);
    			//表示获取返回的内容实体对象
    			HttpEntity entity = response.getEntity();
    			//解析实体中页面的内容,返回字符串形式
    			content = EntityUtils.toString(entity);
    		} catch (ClientProtocolException e) {
    			e.printStackTrace();
    		} catch (IOException e) {
    			e.printStackTrace();
    		}
    		return content;
    	} 
    }

    Processable.java
    import cn.crxy.maven.Spider.domain.Page;
    
    public interface Processable {
    	void process(Page page);
    }
    

    ProcessImpl.java
    import java.util.regex.Matcher;
    import java.util.regex.Pattern;
    
    import org.htmlcleaner.HtmlCleaner;
    import org.htmlcleaner.TagNode;
    import org.htmlcleaner.XPatherException;
    import org.json.JSONArray;
    import org.json.JSONObject;
    
    import cn.crxy.maven.Spider.domain.Page;
    import cn.crxy.maven.Spider.utils.HtmlUtil;
    import cn.crxy.maven.Spider.utils.PageUtil;
    
    public class ProcessImpl implements Processable {
    
    	public void process(Page page) {
    
    		HtmlCleaner htmlCleaner = new HtmlCleaner();
    		TagNode rootNode = htmlCleaner.clean(page.getContent());
    		try {
    			String goodName = HtmlUtil.getText(rootNode, "//*[@id='name']/h1");// 得到商品名称
    			page.setGoodName(goodName);
    
    			String picUrl = HtmlUtil.getAttributeByName(rootNode, "//*[@id='spec-n1']/img","src");// 获取商品图片url
    			page.setPicUrl("http:"+picUrl);
    
    			// 获取商品号
    			String url = page.getDataUrl();
    			Pattern compile = Pattern.compile("http://item.jd.com/([0-9]+).html");
    			Matcher matcher = compile.matcher(url);
    			String goodid = null;
    			if (matcher.find()) {
    				goodid = matcher.group(1);
    				page.setGoodId(goodid);
    			}
    
    			// 获取商品价格
    			// 得到价格的json格式[{"id":"J_1593512","p":"17988.00","m":"17989.00"}]
    			String pricejson = PageUtil
    					.getContent("http://p.3.cn/prices/get?skuid=J_" + goodid);
    			JSONArray jsonArray = new JSONArray(pricejson);
    			JSONObject jsonObject = jsonArray.getJSONObject(0);
    			String price = jsonObject.getString("p");
    			page.setPrice(price);
    
    			// 获取规格参数
    			// *[@id="product-detail-2"]
    			// *[@id="product-detail-2"]/table/tbody/tr[1]/th
    			Object[] evaluateXPath = rootNode
    					.evaluateXPath("//*[@id='product-detail-2']/table/tbody/tr");
    			JSONArray jsonArray2 = new JSONArray();
    			if(evaluateXPath != null && evaluateXPath.length > 0){
    				for(Object object : evaluateXPath){
    					TagNode tagnode = (TagNode) object;
    					if(!"".equals(tagnode.getText().toString().trim())){//有数据
    						
    						Object[] evaluateXPath2 = tagnode.evaluateXPath("/th");
    						JSONObject jsonObject2 = new JSONObject();
    						if(evaluateXPath2.length>0){
    							TagNode tagNode2 = (TagNode) evaluateXPath2[0];
    							jsonObject2.put("name", tagNode2.getText().toString());
    							jsonObject2.put("value", "");
    						}else {
    							
    							Object[] evaluateXPath3 = tagnode.evaluateXPath("/td");
    							TagNode tagNode1 = (TagNode) evaluateXPath3[0];
    							TagNode tagNode2 = (TagNode) evaluateXPath3[1];
    							jsonObject2.put("name", tagNode1.getText().toString());
    							jsonObject2.put("value", tagNode2.getText().toString());
    						}
    						jsonArray2.put(jsonObject2);
    					}
    				}
    			}
    			page.setParam("spec",jsonArray2.toString());
    		} catch (XPatherException e) {
    			e.printStackTrace();
    		}
    	}
    }

    ProcessImpl.java代码中的几个注意点:
    获取商品名称、图片URL的xpath路径



    在京东商品页面获取商品价格的方式


      
    得到如下的连接地址:
    http://p.3.cn/prices/get?type=1&area=1_72_4137&pdtk=&pduid=1112434089&pdpin=&pdbp=0&skuid=J_1593512&callback=cnp
    对连接进行处理后得到如下结果
      
    商品参数规格的Xpath


    Storeable.java
    package cn.crxy.maven.Spider.store;
    
    import cn.crxy.maven.Spider.domain.Page;
    
    public interface Storeable {
    	void store(Page page);
    }

    StoreImple.java
    package cn.crxy.maven.Spider.store;
    
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import java.util.Map;
    
    import cn.crxy.maven.Spider.domain.Page;
    import cn.crxy.maven.Spider.utils.MyDBUtils;
    
    public class StoreImpl implements Storeable {
    
    	public void store(Page page) {
    		String dataUrl = page.getDataUrl();
    		String goodid = page.getGoodId();
    		String goodname = page.getGoodName();
    		String picUrl = page.getPicUrl();
    		String price  = page.getPrice();
    		
    		Map<String, String> values = page.getParam();
    		String param = values.get("spec");
    		
    		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    		String currtime = sdf.format(new Date());
    		MyDBUtils.update(MyDBUtils.INSERT_LOG, goodid,dataUrl,picUrl,goodname,price,param,currtime);
    	}
    
    }

    MyDBUtils.java
    package cn.crxy.maven.Spider.utils;
    
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.util.ArrayList;
    import java.util.List;
    
    import org.apache.commons.dbutils.BasicRowProcessor;
    import org.apache.commons.dbutils.QueryRunner;
    import org.apache.commons.dbutils.handlers.ArrayListHandler;
    
    public class MyDBUtils {
    	private static String className = "com.mysql.jdbc.Driver";
    	private static String url = "jdbc:mysql://localhost:3306/spider?"
    			+ "useUnicode=true&characterEncoding=utf-8";
    	private static String user = "root";
    	private static String password = "1234";
    	private static QueryRunner queryRunner = new QueryRunner();
    
    	public static final String INSERT_LOG = "INSERT INTO SPIDER(good_id,"
    			+ "data_url,pic_url,good_name,price,param,`current_time`) "
    			+ "VALUES(?,?,?,?,?,?,?)";
    
    	// 拒绝new一个实例
    	private MyDBUtils() {
    	};
    
    	static {// 调用该类时既注册驱动
    		try {
    			Class.forName(className);
    		} catch (Exception e) {
    			e.printStackTrace();
    			throw new RuntimeException();
    		}
    	}
    	
    	//查询
    	public static List<String> executeQuerySql(String sql) {
    		List<String> result = new ArrayList<String>();
    		try {
    			List<Object[]> requstList = queryRunner.query(getConnection(), sql,
    					new ArrayListHandler(new BasicRowProcessor() {
    						@Override
    						public <Object> List<Object> toBeanList(ResultSet rs,
    								Class<Object> type) throws SQLException {
    							return super.toBeanList(rs, type);
    						}
    					}));
    			for (Object[] objects : requstList) {
    				result.add(objects[0].toString());
    			}
    		} catch (SQLException e) {
    			e.printStackTrace();
    		}
    		return result;
    	}
    	
    	 //这个方法可以执行一些更新或者新增的sql语句或者删除
    	public static void update(String sql, Object... params) {
    		try {
    			Connection connection = getConnection();
    			queryRunner.update(connection, sql, params);
    			connection.close();
    		} catch (SQLException e) {
    			e.printStackTrace();
    		}
    	}
    
    	// 获取连接
    	private static Connection getConnection() throws SQLException {
    		return DriverManager.getConnection(url, user, password);
    	}
    }
    

    HtmlUtils.java
    import org.htmlcleaner.TagNode;
    import org.htmlcleaner.XPatherException;
    
    public class HtmlUtils {
    	
    	/**
    	 * 根据xpath获取对应标签的内容
    	 * @param tagNode
    	 * @param xpath
    	 * @return
    	 */
    	public static String getText(TagNode tagNode,String xpath){
    		String content = null;
    		Object[] evaluateXPath;
    		try {
    			evaluateXPath = tagNode.evaluateXPath(xpath);
    			if(evaluateXPath!=null && evaluateXPath.length>0){
    				TagNode node = (TagNode)evaluateXPath[0];
    				content = node.getText().toString();
    			}
    		} catch (XPatherException e) {
    			e.printStackTrace();
    		}
    		return content;
    	}
    	
    	/**
    	 * 获取对应标签中指定属性的值
    	 * @param tagNode
    	 * @param xpath
    	 * @param attr
    	 * @return
    	 */
    	public static String getAttributeByName(TagNode tagNode,String xpath,String attr){
    		String content = null;
    		Object[] evaluateXPath;
    		try {
    			evaluateXPath = tagNode.evaluateXPath(xpath);
    			if(evaluateXPath!=null && evaluateXPath.length>0){
    				TagNode node = (TagNode)evaluateXPath[0];
    				content = node.getAttributeByName(attr);
    			}
    		} catch (XPatherException e) {
    			e.printStackTrace();
    		}
    		return content;
    	}
    	
    	
    
    }



    在src/test/java文件夹下面的包中新建test类
    TestSpider.java
    package cn.crxy.maven.Spider;
    
    import org.junit.Test;
    
    import cn.crxy.maven.Spider.domain.Page;
    import cn.crxy.maven.Spider.download.DownloadImpl;
    import cn.crxy.maven.Spider.process.ProcessImpl;
    import cn.crxy.maven.Spider.store.StoreImpl;
    
    public class TestSpider {
    
    	@Test
    	public void test1() throws Exception {
    		Spider spider = new Spider();
    		
    		//给接口注入实现类
    		spider.setDownloadable(new DownloadImpl());
    		spider.setProcessable(new ProcessImpl());
    		spider.setStoreable(new StoreImpl());
    		
    		String url = "http://item.jd.com/1593512.html";
    		Page page = spider.download(url);
    		spider.process(page);
    		spider.store(page);
    
    	}
    }
    

    运行test测试方法,在数据库中插入了数据



    展开全文
  • Java爬虫爬取京东商城

    2022-02-23 23:23:00
    旨在通过使用java爬虫,提取网络中的各种商品信息,并收集的商品信息建立统一数据模型存储数据,通过数据模型描述商品的基本属性。如spu,sku,商品描述,价格等信息,同时需要剔除非必要信息,做到精准分析。根据所...

    一、任务:

    旨在通过使用java爬虫,提取网络中的各种商品信息,并收集的商品信息建立统一数据模型存储数据,通过数据模型描述商品的基本属性。如spu,sku,商品描述,价格等信息,同时需要剔除非必要信息,做到精准分析。根据所获取的信息提供商品展示页面,通过搜索,得到商品数据信息。抓取商品数据,建立统一数据模型,模型的可扩展性,商品数据展示。

    目的:该项目有利于简单理解java的爬虫过程,spring boot简单的项目调试,调用,映射方式,数据库连接,帮助理解的前后端交互原理。

    二、类及数据的设计

    2.1项目的开发环境

    2.2系统功能结构设计

    该程序主要通过调用webmagic使用爬虫功能爬取数据,建立数据模型,利用MySQL存储数据。查询调用数据库内容,模型的可扩展性,通过html/css提供web页面展示。

    2.2.1数据爬取,数据模型建立

    WebMagic:

    WebMagic的结构分为Downloader、PageProcessor、Scheduler、Pipeline四大组件,并由Spider将它们彼此组织起来。

    1)Downloader:负责从互联网上下载页面,以便后续处理。WebMagic默认使用了Apache HttpClient作为下载工具。

    2)PageProcessor:负责解析页面,抽取有用信息,以及发现新的链接。WebMagic使用Jsoup作为HTML解析工具,并基于其开发了解析XPath的工具Xsoup。在这四个组件中,PageProcessor对于每个站点每个页面都不一样,是需要使用者定制的部分。

    3)Scheduler:负责管理待抓取的URL,以及一些去重的工作。WebMagic默认提供了JDK的内存队列来管理URL,并用集合来进行去重。也支持使用Redis进行分布式管理。除非项目有一些特殊的分布式需求,否则无需自己定制Scheduler。

    4)Pipeline:负责抽取结果的处理,包括计算、持久化到文件、数据库等。WebMagic默认提供了“输出到控制台”和“保存到文件”两种结果处理方案。Pipeline定义了结果保存的方式,如果你要保存到指定数据库,则需要编写对应的Pipeline。对于一类需求一般只需编写一个Pipeline。

    Selenium:

    Selenium是一个Web的自动化测试工具,可以根据我们的指令,使用代码控制浏览器,让浏览器自动加载页面,获取需要的数据,甚至页面截屏,或者判断网站上某些动作是否发生,支持主流的浏览器

    该程序使用Downloader、PageProcessor、Pipeline,Spider组件进行爬虫,建立数据模型。通过selenium对谷歌无头浏览器进行自动化操作。

    1、定时任务

    在springboot工程中使用定时器。在工程中创建一个普通的类,添加注解@Component,

    在定义方法上使用@Scheduled注解标注,配置定期执行时间,在spring boot工程的引导类上添加@EnableScheduling注解。

    2、设置代理

    使用代理服务器发起请求,防止反爬策略封ip

    代理服务器流程:

    爬虫服务器 -> 代理服务器 -> 目标服务器

    目标服务器 -> 代理服务器 -> 爬虫服务器 ->解析数据

    可用的免费代理:

    免费私密代理 - 米扑代理

    http://www.xiladaili.com/gaoni/

    3、使用selenium+无头浏览器抓取数据

    通过Maven添加Selenium依赖。Selenium是一个前端的测试框架,通过Selenium使用代码控制浏览器。

    无头浏览器:没有界面的浏览器,解析js。得到一些默认不到的数据。用于各类测试场景,在任何给定页面上可采取的频繁重复的操作,反复测试。

    4、使用浏览器渲染,抓取京东商城的数据并保存

    1)PageProcess解析html

            1. 判断是列表页面还是详细页面 

            2. 如果是列表页面

                    a、解析列表中的商品数据,去sku和spu,封装成一个对象,传递给pipeline

                    b、解析商品的链接地址,把地址添加到访问队列中

                    c、翻页处理,设置固定url:Enterprise Cybersecurity Solutions, Services & Training | Proofpoint US 添加一个附件:当前请求的url

            3. 如果是详细页面

                    a、解析商品的详细信息

                    b、把详细信息封装成一个商品对象

                    c、传递给pipeline

    2)Downloader下载页面

     

            1. 抓取列表页面

                    a、访问url

                    b、页面滚动到最下方

                    c、从浏览器中取html

                    d、需要把结构封装成Page对象

            2. 如果是详情页面

                    a、直接访问url

                    b、取html,封装成Page,返回

            3. 如果是翻页处理

                    a、从Request对象中取附件,翻页之前的url

                    b、访问url

                    c、点击翻页按钮,翻到第二页

                    d、让页面滚到最下方,加载30条数据

                    e、把去浏览器渲染的html结果封装成Page对象返回

    3)Pipeline保存到数据库

            创建数据库表,创建对应的属性

    5、模型的可扩展性

            基于springboot的控制反转,类与类之间没有很强的耦合性,具有很好的“特性:“高内聚、低耦合”实例化的操作交给Spring 的bean工厂,通过xml配置文件去记录。所以模型具有很强的可扩展性。只需在Item中添加属性,并添加对应的浏览器操作。

    2.2.2 SpringBoot+Ajax+MyBatis查询操作数据库

    开发顺序

            后端SpringBoot+MyBatis, 前端Ajax+jQuery+CSS+HTML,通过爬虫操作得到数据,根据数据对于后端接口数据设计和使用,前端数据请求和响应填充界面的过程,数据库采用MySQL 8.0.26,用于学习掌握前后端开发的关键技术和开发架构。

            随着 Spring Boot 越来越流行,MyBatis 也开发了一套基于 Spring Boot 模式的 starter:mybatis-spring-boot-starter。

     

    entity层:存放的是实体类,属性值与数据库值保持一致,实现 setter 和 getter 方法。

    dao层:即 mapper层,对数据库进行持久化操作,他的方法使针对数据库操作的,基本上用的就是增删改查。作为接口,只有方法名,具体实现在mapper.xml中实现。

    service层:业务层,存放业务逻辑处理,不直接对数据库进行操作,有接口和接口实现类,提供 controller 层调用方法。

    controller层:控制层,导入 service层,调用你service方法,controller通过接受前端传来的参数进行业务操作,在返回一个制定的路径或数据表。

    选择ajax原因是基于爬虫操作数据量大,变化多,AJAX能提供在无需重新加载整个网页的情况下,能够更新部分网页的技术。AJAX 是一种用于创建快速动态网页的技术。通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。

    而选择MyBatis,因为MyBatis可以使用简单的XML或注释进行配置,并将图元,映射接口和 POJO映射到数据库记录。消除了大部分JDBC代码以及参数的手动设置和结果检索。同时基于MyBatis灵活特性,不会对应用程序或者数据库的现有设计强加任何影响,SQL写在XML里,从程序代码中彻底分离,降低耦合度,更加为程序的可拓展性提供基础。

     三、部分代码

    3.1爬虫部分

    @Override
         public void process(Page page) {
             String level = page.getRequest().getExtra("level").toString();
             switch (level){
                 case "list":
                     parseList(page);
                     break;
                 case "detail":
                     praseDetail(page);
                     break;
             }
    
    /**
          * 解析详情页
          *
          * @param page
          */
         private void praseDetail(Page page) {
             Html html = page.getHtml();
             String title = html.$("div.master .p-name").xpath("///allText()").get();
             String priceStr = html.$("div.summary-price-wrap .p-price span.price").xpath("///allText()").get();
             String pic = "https:"+html.$("#spec-img").xpath("///@src").get();
             String url = "https:"+html.$("div.master .p-name a").xpath("///@href").get();
             String sku = html.$("a.notice.J-notify-sale").xpath("///@data-sku").get();
     
             Item item = new Item();
             item.setTitle(title);
             item.setPic(pic);
             item.setPrice(Float.valueOf(priceStr));
             item.setUrl(url);
             item.setUpdated(new Date());
             item.setSku(StringUtils.isNotBlank(sku)?Long.valueOf(sku) : null);
     
             // 单条数据塞入
             page.putField("item", item);
         }
    
     /**
          * 解析列表页
          * @param page
          */
         private void parseList(Page page) {
             Html html = page.getHtml();
             // 这里拿到sku 和 spu 并交给pipeline
             List<Selectable> nodes = html.$("ul.gl-warp.clearfix > li").nodes();
             List<Item> itemList = new ArrayList<>();
             for (Selectable node : nodes) {
                 // 拿到sku和spu
                 String sku = node.$("li").xpath("///@data-sku").get();
                 String spu = node.$("li").xpath("///@data-spu").get();
                 String href = "https:" + node.$("div.p-img a").xpath("///@href").get();
     
                 Item item = new Item();
                 item.setSku(Long.valueOf(sku));
                 item.setSpu(StringUtils.isNotBlank(spu) ? Long.valueOf(spu) : 0);
                 item.setCreated(new Date());
                 itemList.add(item);
     
                 // 同时还需要把链接加到详情页 加到队列
                 Request request = new Request(href);
                 request.putExtra("level", "detail");
                 request.putExtra("pageNum", page.getRequest().getExtra("pageNum"));
                 request.putExtra("detailUrl", href);
                 page.addTargetRequest(request);
             }
     
             // 以集合的方式存入
             page.putField("itemList", itemList);
     
             // 同时还要去做分页
             String pageNum = page.getRequest().getExtra("pageNum").toString();
             if ("1".equals(pageNum)){
                 Request request = new Request("https://nextpage.com");
                 request.putExtra("level", "page"); // 标识去分页
                 request.putExtra("pageNum", (Integer.valueOf(pageNum) + 1) + "");// 页码要+1 接下来要的是第二页
                 // 添加到队列
                 page.addTargetRequest(request);
             }

    3.2 spring boot查询操作数据库

    Control控制层:
    
    @RestController//返回rest服务类型的数据格式
     @RequestMapping("/Jd")//数据接口controller怎么被调用
     public class ItemController {
         //调用一些方法得到返回值,把服务层作为对象
         @Autowired//自动注入,生成实例
         private ItemService itemService;//好封装
     
         @GetMapping("/getJd")//路径如果是Jd下的getJd,会获得前端传来的参数‘id',获得值,把id值传到findById方法中
         public String getItem(@Param("id")Integer id){
             Item item = itemService.findById(id);
             return item.getTitle();
         }
         @GetMapping("/getId") // 通过title// 获取id
         public Integer getId(@Param("Message") String title){
             Item item = itemService.findByTitle(title);
             return item.getId();
         }
     
         @GetMapping("/getOne") // 通过title// 获取id,一条数据记录
         public Item getAll(@Param("id") Integer id){
             Item item = itemService.findById(id);
             return item;
         }
     
         @GetMapping("/getJson") // 通过title获取id
         public String getJson(@Param("id") Integer id) {
             Item item = itemService.findById(id);
             Gson gson = new Gson();
             return gson.toJson(item);
         }
         @GetMapping("/getAll") // 通过title获取id,获得多条数据
         public List<Item> getAll(){
             List<Item> list = itemService.findItemAll();
             return list;
         }
     
         @GetMapping("/getAllJson") // 通过title获取id
         public String getAllJson(){
             List<Item> list = itemService.findItemAll();
             Gson gson = new Gson();
             return gson.toJson(list);
         }
    }

    3.3前端设计

    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" type="text/css"href="https://cdn.bootcss.com/bootstrap/4.0.0-beta.2/css/bootstrap.min.css">
    <script type="text/javascript"src="https://cdn.bootcss.com/jquery/1.4.0/jquery.js"></script>
    <script>
    $(document).ready(function(){
    $("#btn1").click(function(){
    test1();
    });
    
    $("#btn2").click(function(){
    $.test2();
    });
    });
    //data为数组
    function test1(){
    //alert("Text1: " + $("#test").text());
    $.ajax({
    url:'/msg/getAllJson',//访问后台接口,用get,后台返回json
    type:'get',
    dataType:'json',
    success:function(data){
    $("#tabletest").find('tr').remove();
    tr='<td>id</td><td>title</td>'
    $("#tabletest").append('<tr>'+tr+'</tr>')
    //方法中传入的参数data为后台获取的数据
    for(i in data) //data指的是数组,i为数组的索引
    {
    var tr;
    tr='<td>'+data[i].id+'</td>'+'<td>'+data[i].title +'</td>'
    $("#tabletest").append('<tr>'+tr+'</tr>')
    }
    }
    });
    }
    </script>
    <style type="text/css">
    .center{
    margin: auto;
    text-align:center;
    font-size: 24px;
    width: 60%;
    background: lightblue;
    }
    </style>
    </head>
    <body>
    <div class="center">
    <p id="test">Springboot整合MyBatis通过ajax查询MySQL数据库数据</b></p>
    <button id="btn1">显示所有数据</button>
    <button id="btn2">查询</button>
    <input id="id" name="id" type="text" placeholder="请输入id值"/>
    <br>
    <table class="table table-bordered" id='tabletest'>
    </table>
    </div>
    </body>
    </html>

    四、程序运行、测试与分析

    4.1程序运行

     

    4.2总结分析

    1. 在使用java程序应注意jdk版本问题,以及jdk对应的数据库版本。
    2. 在使用数据库操作时,应注意数据库与idea连接application中的url,username,password格式问题。
    3. 应注意传入数据文件路径相对绝对路径问题。
    4. 学习通过debug,逐步了解一个项目的进程,排除错误。
    5. 在调试程序中,应该带着思考搜索解决方式,逐一排除造成错误的原因。
    6. 了解各种注释API作用,有助于优化代码。
    7. 对于繁多的技术,需要从需求出发,合理选择合适,高效,可拓展的技术。
    8. 通过程序更加深入了解前后端工作方式,更加理解springboot的工作原理。

    4.3改进方案

    4.3.1对于爬虫:

            首先可以通过更高效的框架加快爬虫速度,实现更加灵活的定制化爬取。其次,可以通过优化算法,对于一些爬取失败或数据获取失败的记录进行汇总,在页面反馈成功完整数据,通过网页分析算法过滤主题无关的链接。

            交互问题是一个需要解决的问题,爬取会页面涉及到用户信息输入,验证码处理,随着各类花样繁多的验证码的出现,爬虫遇到这种情况会很难处理。

            Javascript 解析问题,目前大多数网页属于动态网页,网页中大多数有用的数据都是通过ajax/fetch动态获取后然后再由js填充到网页,单纯的html静态页面中有用的数据很少。让后台脚本去做javascript操作会很麻烦,不仅需要清楚的理解原网页代码逻辑也会让代码显得很臃肿。

            ip解析问题,尽管在本程序使用代理ip,但这仍然是爬虫会遇到的最致命问题。网站防火墙会对某个ip在某段时间内请求的次数做限制,如果超过上限则拒绝请求。后台爬取时机器和ip有限,很容易达到上线而导致请求被拒绝。目前主要的应对方案是使用代理,这样一来ip的数量就会多一些,但代理ip依然有限。

    4.3.2.前端太丑,过于简陋

    展开全文
  • 下面小编就为大家分享一篇Java爬虫实现爬取京东上的手机搜索页面 HttpCliient+Jsoup,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
  • 将页面滑到最底部,因为京东页面若不滑到最下面会导致有些数据加载不出来 ((JavascriptExecutor)webDriver).executeScript("window.scrollTo(0,document.body.scrollHeight)"); 获取源码 String pageSource = ...

    准备

    配置maven环境
    下载浏览器驱动,并引入;

    下载浏览器驱动

    前往华为云镜像站下载谷歌浏览器驱动

    https://mirrors.huaweicloud.com/home 
    

    在这里插入图片描述
    要下载与自己电脑上谷歌浏览器版本相匹配的;

    引入pom.xml依赖

            <dependency>
                <groupId>org.seleniumhq.selenium</groupId>
                <artifactId>selenium-java</artifactId>
                <version>3.141.59</version>
            </dependency>
    
            <dependency>
                <groupId>org.seleniumhq.selenium</groupId>
                <artifactId>selenium-api</artifactId>
                <version>3.141.59</version>
            </dependency>
    

    开始爬取

    目标网址

    https://search.jd.com/Search?keyword=iphone%2013&psort=3&wq=iphone%2013&psort=3&pvid=37f665a84459460eb713df08bdcd7799&page=1&s=1&click=0
    

    在这里插入图片描述
    目标是爬取所有47页的商品的 价格,商品名称,商品描述;

    第一页网址:

    https://search.jd.com/Search?keyword=iphone%2013&psort=3&wq=iphone%2013&psort=3&pvid=37f665a84459460eb713df08bdcd7799&page=1&s=1&click=0

    第二页网址:

    https://search.jd.com/Search?keyword=iphone%2013&psort=3&wq=iphone%2013&psort=3&pvid=37f665a84459460eb713df08bdcd7799&page=3&s=61&click=0

    第三页网址:

    https://search.jd.com/Search?keyword=iphone%2013&psort=3&wq=iphone%2013&psort=3&pvid=37f665a84459460eb713df08bdcd7799&page=5&s=121&click=0

    经过分析发现规律: page=1 , 3 , 5 为奇数 --2i+1
    s =1,60,121 依次加60-- ((i-1)*60)+1

    主要代码与操作步骤

    定义一个浏览器对象

    ChromeDriver webDriver = new ChromeDriver();
    

    利用循环爬取45页的数据

    for(int i=1;i<45;i++) {
                webDriver.get("https://search.jd.com/search?keyword=iphone%2013&wq=iphone%2013&cid3=655&psort=3&page="+((2*i)-1)+"&s="+((i-1)*60)+1+"&click=0");
    

    将页面滑到最底部,因为京东页面若不滑到最下面会导致有些数据加载不出来

    ((JavascriptExecutor)webDriver).executeScript("window.scrollTo(0,document.body.scrollHeight)");
    

    获取源码

     String pageSource = webDriver.getPageSource();
    

    选中一个单元获取其路径
    在这里插入图片描述

    #J_goodsList > ul > li:nth-child(13) > div
    
    #J_goodsList > ul > li:nth-child > div
    

    查看价格路径
    在这里插入图片描述

    #J_goodsList > ul > li:nth-child(16) > div > div.p-price > strong > i
    

    在其循环体下

     div.p-price > strong > i
    

    同理:店铺名称路径 div.p-shop > span > a
    商品描述路径:div.p-name.p-name-type-2 > a > em
    在这里插入图片描述在这里插入图片描述

    还要创建一个product类并建对象:

    在这里插入图片描述

    package com.zygxy.shop;
    
    public class Product {
        private String price;
        private String shopname;
        private String shopcontext;
    
        public String getPrice() {
            return price;
        }
    
        public void setPrice(String price) {
            this.price = price;
        }
    
        public String getShopname() {
            return shopname;
        }
    
        public void setShopname(String shopname) {
            this.shopname = shopname;
        }
    
        public String getShopcontext() {
            return shopcontext;
        }
    
        public void setShopcontext(String shopcontext) {
            this.shopcontext = shopcontext;
        }
    }
    

    全部代码

    package com.zygxy.shop;
    
    import com.alibaba.fastjson.JSONObject;
    import lombok.extern.slf4j.Slf4j;
    import org.jsoup.Jsoup;
    import org.jsoup.nodes.Document;
    import org.jsoup.nodes.Element;
    import org.jsoup.select.Elements;
    import org.openqa.selenium.JavascriptExecutor;
    import org.openqa.selenium.chrome.ChromeDriver;
    
    import java.io.IOException;
    import java.util.Properties;
    @Slf4j
    public class JD {
        public static void main(String[] args) throws IOException {
            Properties properties = new Properties();
            properties.load(JD.class.getClassLoader().getResourceAsStream("application.properties"));
            System.out.println(properties.getProperty("chromedriver"));
            System.setProperty("webdriver.chrome.driver",properties.getProperty("chromedriver"));
            ChromeDriver webDriver = new ChromeDriver();
            for (int i=1;i<45;i++){
                webDriver.get("https://search.jd.com/search?keyword=iphone%2013&psort=3&wq=iphone%2013&psort=3&pvid=aa23e9f58a714e9087f316ab6aa993bd&cid3=655&cid2=653&page="+((2*i)-1)+"&s="+((i-1)*60)+1+"&click=0");
                ((JavascriptExecutor) webDriver).executeScript("window.scrollTo(0,document.body.scrollHeight)");
                String pageSource = webDriver.getPageSource();
                Document parse = Jsoup.parse(pageSource);
                Elements select = parse.select("#J_goodsList > ul > li > div ");
                for(Element e : select){
                    Product product = new Product();
                    Element price = e.selectFirst(" div.p-price > strong > i");
                    product .setPrice(price.text());
                    Element shop_name = e.selectFirst(" div.p-shop > span > a");
                    product.setShopname(shop_name.text());
                    Element shopcontext  = e.selectFirst(" div.p-name.p-name-type-2 > a > em");
                    product.setShopcontext(shopcontext.text());
                    String json = JSONObject.toJSONString(product);
                    log.info(json);
                }
            }
        }
    }
    

    pom.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>org.example</groupId>
        <artifactId>NovelParse</artifactId>
        <version>1.0-SNAPSHOT</version>
    
        <properties>
            <maven.compiler.source>8</maven.compiler.source>
            <maven.compiler.target>8</maven.compiler.target>
        </properties>
    
    
        <dependencies>
            <!-- https://mvnrepository.com/artifact/org.jsoup/jsoup -->
            <dependency>
                <groupId>org.jsoup</groupId>
                <artifactId>jsoup</artifactId>
                <version>1.13.1</version>
            </dependency>
    
            <!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
            <dependency>
                <groupId>commons-io</groupId>
                <artifactId>commons-io</artifactId>
                <version>2.4</version>
            </dependency>
    
            <!-- https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java -->
            <dependency>
                <groupId>org.seleniumhq.selenium</groupId>
                <artifactId>selenium-java</artifactId>
                <version>3.141.59</version>
            </dependency>
    
            <!-- https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-api -->
            <dependency>
                <groupId>org.seleniumhq.selenium</groupId>
                <artifactId>selenium-api</artifactId>
                <version>3.141.59</version>
            </dependency>
    
    
    
            <!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>fastjson</artifactId>
                <version>1.2.75</version>
            </dependency>
    
            <!-- https://mvnrepository.com/artifact/ch.qos.logback/logback-core -->
            <dependency>
                <groupId>ch.qos.logback</groupId>
                <artifactId>logback-core</artifactId>
                <version>1.2.3</version>
            </dependency>
    
            <!-- https://mvnrepository.com/artifact/ch.qos.logback/logback-classic -->
            <dependency>
                <groupId>ch.qos.logback</groupId>
                <artifactId>logback-classic</artifactId>
                <version>1.2.3</version>
            </dependency>
    
    
    
            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-api</artifactId>
                <version>1.7.25</version>
                <scope>compile</scope>
            </dependency>
    
    
            <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>1.18.12</version>
                <scope>provided</scope>
            </dependency>
        </dependencies>
    
    
        <build>
            <plugins>
                <!-- 如果已经在Maven的全局配置中,配置了JDK编译的界别,这个插件可以省略 -->
                <!-- <plugin>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>2.3.2</version>
                    <configuration>
                        <source>1.8</source>
                        <target>1.8</target>
                    </configuration>
                </plugin> -->
    
                <!--mvn:package阶段使用
                        maven-assembly-plugin可以将当前项目依赖的Jar中的字节码也打包!
                        默认的打包插件maven-jar-plugin,只会将自己写的代码打包,默认仓库中已经安装了所需的依赖!
                -->
                <plugin>
                    <artifactId>maven-assembly-plugin</artifactId>
                    <configuration>
                        <descriptorRefs>
                            <descriptorRef>jar-with-dependencies</descriptorRef>
                        </descriptorRefs>
                        <archive>
                            <manifest>
                                <mainClass>com.zygxy.JD</mainClass>
                            </manifest>
                        </archive>
                    </configuration>
                    <executions>
                        <execution>
                            <id>make-assembly</id>
                            <phase>package</phase>
                            <goals>
                                <goal>single</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>
            </plugins>
        </build>
    </project>
    

    resources配置

    在这里插入图片描述application.properties
    本地驱动地址
    chromedriver =E:\shixun\pachong\src\main\resources\chromedriver.exe
    在这里插入图片描述
    logback.xml 定义了日志的输出地址和格式

    <?xml version="1.0" encoding="UTF-8"?>
    <configuration>
        <property name="LOG_HOME" value="d://shoplog" />
        <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
            <encoder>
                <pattern>%msg%n</pattern>
            </encoder>
        </appender>
    
        <appender name="rollingFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
            <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
                <fileNamePattern>${LOG_HOME}/shop.%d{yyyy-MM-dd}.log</fileNamePattern>
            </rollingPolicy>
            <encoder>
                <pattern>%msg%n</pattern>
            </encoder>
        </appender>
    
    
        <!-- 日志输出级别 -->
        <root level="INFO">
            <appender-ref ref="rollingFile"/>
            <appender-ref ref="console" />
    
        </root>
    
    </configuration>
    
    展开全文
  • 本文是在学习java爬虫时,跟着视频做的一个小项目,本文会着重介绍其中会遇到的问题及重要代码实现。
  • 这段时间一直在做 Java 爬虫的相关开发,在与众多网站平台(其实也就几个 )的斗智斗勇中也稍有一点心得,今天就使用 Java 爬取一下x东的商品评论信息来记录一下,如果有什么错误或不足之处,也烦请各位大佬指出,...
  • Java爬虫爬取京东

    2020-08-27 23:26:08
    首先访问京东,搜索手机,分析页面,我们抓取以下商品数据: 商品图片、价格、标题、商品详情页 SPU和SKU 除了以上四个属性以外,我们发现上图中的苹果手机有四种产品,我们应该每一种都要抓取。那么这里就必须要...
  • Java多线程爬虫爬取京东商品信息

    千次阅读 2017-07-24 15:44:35
    前言网络爬虫,是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本。爬虫可以通过模拟浏览器访问网页,从而...最近准备做一个电商网站,商品的原型就打算从一些电商网站上爬取,这里使用了HttpClient和Jsoup实
  • 以下内容转载于...Maven地址org.jsoupjsoup1.11.2网页分析:商品布局分析:测试代码实例:importorg.jsoup.Jsoup;importorg.jsoup.nodes.Document;importorg.jsoup.nodes.Element;...
  • Java爬虫(对京东图书分类,分类明细,商品列表), CREATE DATABASE `java_reptilian` CREATE TABLE `booksort` ( `id` int(11) NOT NULL AUTO_INCREMENT, `sort_name` varchar(50) DEFAULT NULL, PRIMARY KEY...
  • 这是基于Springboot的网络爬虫-京东商品页的源码,可供大家免费下载 Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置,从而...
  • 基于SpringBoot的Java爬虫项目-京东商品页爬取(部分)效果图遇到的各种BUG项目目录结构具体代码详解配置文件添加依赖application.properties文件dao目录下ItemDao类jd.pojo目录下Item类service目录下的...
  • 爬取京东手机商品信息(本人采用JAVA的MVEN工程)用时两天左右 最近喜欢上研究爬虫的问题了,发现还是很好用的,特别是这里运用了SpringBoot框架正是我最近在学的知识。 技术栈:SpringBoot、Mysql、JpaRepository、...
  • 引入jar包: <dependency> ...selenium-java</artifactId> <version>3.141.59</version> </dependency> java代码: package com.jd.demo; import org.openqa.
  • 1,导入数据库 // 创建crawler数据库, 再创建表 ... `spu` bigint(15) DEFAULT NULL COMMENT '商品集合id', `sku` bigint(15) DEFAULT NULL COMMENT '商品最小品类单元id', `title` varchar(100) DEFAULT NULL COM
  • c#利用WebClient和WebRequest获取京东网页商品信息评价数、商品价格、活动标语等。
  • 主要介绍了Java爬虫Jsoup+httpclient获取动态生成的数据的相关资料,需要的朋友可以参考下
  • java爬取京东数据

    2018-08-10 09:24:35
    java爬取京东数据,利用java的dom类,运用request获取前端页面的dom,再通过特定的格式获取对应的标签。
  • 基于JAVA京东商品分布式爬虫系统的设计与实现.pdf
  • 利用Java实现爬取淘宝、京东、天猫某商品信息。 导入jsoup包 jsoup 是一款Java 的HTML解析器,可直接解析某个URL地址、HTML文本内容。它提供了一套非常省力的API,可通过DOM,CSS以及类似于jQuery的操作方法来取出和...
  • 最近在学习java爬虫技术,学的是黑马的视频资源,由于是几年前的视频啦,京东页面有些许变化,在此记录我遇到的问题,使用的爬虫技术是httpClient和jsoup,项目搭建使用的springboot+ jpa。首先给出主页的代码:@...
  • 基于JAVA京东商品分布式爬虫系统的设计与实现
  • 爬虫不多做介绍,本文用于对自己入门爬虫的记录 JDK爬虫简单模板 import org.junit.Test; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.io....
  • 近来,云计算结课要求是要做一个基于Hadoop组件的电商...下面,作为爬虫的入门,我用Jsoup来实现一下京东商品数据的采集。 首先,和任何项目前提一样,新建一个项目,配置好依赖。 <dependency> <groupId&
  • Java爬虫爬取 天猫 淘宝 京东 搜索页和 商品详情 先识别商品url,区分平台提取商品编号,再根据平台带着商品编号爬取数据。 1.导包 <!-- 爬虫相关Jar包依赖 --> <dependency> <groupId>org....

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 3,719
精华内容 1,487
关键字:

java爬虫京东商品

java 订阅