java使用xpath及获取scrip内容爬取网站数据各种心得

news/2024/5/10 11:20:18/文章来源:https://blog.csdn.net/qq_42248939/article/details/88917287

  最近一直在用java做爬虫,都是一些没有技术含量的活,仔细想一下底层用到的大概有这算法,一个是匹配算法、一个关于树的算法,全都给我们封装好了,java真是方便、无脑,当然也很low,但是个人原因,工作效率并不高?,成果勉勉强强爬取了京东、天猫、淘宝、阿里巴巴,这几个电商搜索框架网站,虽然天猫、淘宝、阿里巴巴都是一家的,但是他们却一点都不一样,其中阿里巴巴最难爬,时常在想,这一年来自学的spring、springboot、springmvc、mybatis全都是一些框架调用别人的接口,实际上感觉啥都没学到,出去工作也是你懂的别人都懂,充其量只能算是码农,搬运代码的农名,如何才能跳出自我的境界,做一个永远逃离井底的井底之蛙,成为一个真真正正的程序员,是一件值得思考的问题。

1、java如何支持xpath:首先是我的目录,其中标红色就是核心使用部分,其他没啥用(个人扩展)。

                                                      

 

 

  • maven项目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>com.etoak</groupId><artifactId>crawl</artifactId><version>1.0-SNAPSHOT</version><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><configuration><source>7</source><target>7</target></configuration></plugin></plugins></build><dependencies><dependency><groupId>com.googlecode.juniversalchardet</groupId><artifactId>juniversalchardet</artifactId><version>1.0.3</version></dependency><dependency><groupId>org.kie.modules</groupId><artifactId>org-apache-commons-httpclient</artifactId><version>6.2.0.CR2</version><type>pom</type></dependency><dependency><groupId>org.jsoup</groupId><artifactId>jsoup</artifactId><version>1.9.2</version></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>3.1</version></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>3.1</version></dependency><dependency><groupId>commons-lang</groupId><artifactId>commons-lang</artifactId><version>2.6</version></dependency><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><version>1.7.25</version></dependency><dependency><groupId>org.jsoup</groupId><artifactId>jsoup</artifactId><version>1.10.3</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.47</version></dependency><dependency><groupId>com.vaadin.external.google</groupId><artifactId>android-json</artifactId><version>0.0.20131108.vaadin1</version></dependency></dependencies></project>
  • 首先是JsoupParserUtils.java,显然这是一个工具类,用来支持xpath的各种方法
package com.etoak.crawl.util;import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;import javax.xml.namespace.QName;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;
import org.apache.commons.lang.StringUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Attribute;
import org.jsoup.select.Elements;
import org.jsoup.select.NodeTraversor;
import org.jsoup.select.NodeVisitor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Comment;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;
import com.sun.org.apache.xerces.internal.dom.ElementImpl;/*** Jsoup的xpath解析工具类* * @author liuhh**/
@SuppressWarnings("restriction")
public class JsoupParserUtils {protected final static DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();private final static Logger log = LoggerFactory.getLogger(JsoupParserUtils.class);private final static XPath xPath = XPathFactory.newInstance().newXPath();protected static TransformerFactory tf = TransformerFactory.newInstance();private static final Lock LOCK = new ReentrantLock();/*** 得到该节点的子节点个数* * @param ele* @param xpath* @return*/public static int getEleChildNum(final org.jsoup.nodes.Element ele, final String xpath) {try {Object res = parse(ele, xpath, XPathConstants.NODESET);if (null != res && res instanceof NodeList) {NodeList nodeList = (NodeList) res;return nodeList == null ? 0 : nodeList.getLength();}} catch (Exception e) {log.error("根据xpath:{},获取子节点个数出现错误,错误原因:" + e.getMessage(), xpath);}return 0;}/*** 判断文档中是否存在xpath节点* * @param ele* @param xpath* @return*/public static boolean exists(final org.jsoup.nodes.Element ele, final String xpath) {try {Object res = parse(ele, xpath, XPathConstants.BOOLEAN);if (null != res && res instanceof Boolean) {return (boolean) res;}return false;} catch (Exception e) {log.error("检查xpath:{},是否存在时出现错误,!" + e.getMessage(), xpath);}return false;}/*** 根据xpath得到w3c的Element对象* * @param ele* @param xpath* @return*/public static ElementImpl getW3cElementImpl(final org.jsoup.nodes.Element ele, final String xpath) {try {Object res = parse(ele, xpath, XPathConstants.NODE);if (null != res && res instanceof ElementImpl) {return (ElementImpl) res;}return null;} catch (Exception e) {log.error("根据xpath:{},得到w3c的Element对象出现错误,原因:" + e.getMessage(), xpath);}return null;}/*** 根据xpath得到jsoup的Element对象* * @param ele* @param xpath* @return*/public static org.jsoup.nodes.Element getJsoupElement(final org.jsoup.nodes.Element ele, final String xpath) {try {Object res = parse(ele, xpath, XPathConstants.NODE);if (null != res && res instanceof ElementImpl) {ElementImpl elementImpl = (ElementImpl) res;return getJsoupEle(elementImpl);}return null;} catch (Exception e) {log.error("根据xpath:{},得到jsoup的Element对象出现错误,原因:" + e.getMessage(), xpath);}return null;}/*** 根据xpath得到jsoup的Elements对象* * @param ele* @param xpath* @return*/public static Elements getJsoupElements(final org.jsoup.nodes.Element ele, final String xpath) {try {NodeList nodeList = getNodeList(ele, xpath);if (null != nodeList && nodeList.getLength() > 0) {int len = nodeList.getLength();Elements elements = new Elements();for (int i = 0; i < len; i++) {Node node = nodeList.item(i);if (null != node && node instanceof ElementImpl) {org.jsoup.nodes.Element element = getJsoupEle(((ElementImpl) node));elements.add(element);}}return elements;}} catch (Exception e) {log.error("根据xpath:{},得到jsoup的Element对象出现错误,原因:" + e.getMessage(), xpath);}return null;}/*** 从Jsoup的Element中解析出W3C的NodeList* * @param ele* @param xpath* @return*/public static NodeList getNodeList(final org.jsoup.nodes.Element ele, final String xpath) {try {Object res = parse(ele, xpath, XPathConstants.NODESET);if (null != res && res instanceof NodeList) {return (NodeList) res;}} catch (Exception e) {log.error(e.getMessage(), e);}return null;}/*** 得到节点的某一个属性值* * @param ele* @param xpath* @return*/public static String getXpathString(final org.jsoup.nodes.Element ele, final String xpath) {try {int textNum = getEleChildNum(ele, xpath);if (1 == textNum) {Object res = parse(ele, xpath, XPathConstants.STRING);if (null != res) {return res.toString();}} else {List<String> res = getXpathListString(ele, xpath);if (res != null && res.size() > 0) {StringBuilder stringBuilder = new StringBuilder();for (Iterator<String> iterator = res.iterator(); iterator.hasNext();) {String text = iterator.next();if (null != text) {stringBuilder.append(text.replace("\r\n", "."));}}return stringBuilder.toString();}}return null;} catch (Exception e) {e.printStackTrace();log.error("根据xpath:{}查询字符串时出现错误:" + e.getMessage(), xpath);}return null;}/*** 查询字符串列表* * @param ele* @param xpath* @return*/public static List<String> getXpathListString(final org.jsoup.nodes.Element ele, final String xpath) {try {Object res = parse(ele, xpath, XPathConstants.NODESET);if (null != res && res instanceof NodeList) {NodeList nodeList = (NodeList) res;int length = nodeList.getLength();if (length <= 0) {return null;}List<String> list = new ArrayList<>();for (int i = 0; i < length; i++) {Node node = nodeList.item(i);list.add(null == node ? null : node.getNodeValue());}return list;}return null;} catch (Exception e) {log.error("根据xpath:{}查询字符串列表时出现错误:" + e.getMessage(), xpath);}return null;}/*** 获取xpath解析结果* * @param doc* @param xPathStr* @param qName* @return*/public static Object parse(final org.jsoup.nodes.Element doc, final String xPathStr, final QName qName) {Node node = fromJsoup(doc);return parse(node, xPathStr, qName);}/*** * @param doc* @param xPathStr* @param qName* @return*/public static Object parse(final Node doc, final String xPathStr, final QName qName) {try {if (doc == null) {log.warn("解析文档为null!");return null;}if (StringUtils.isBlank(xPathStr)) {log.warn("解析的Xpath路径为空!");return null;}if (null == qName) {log.warn("解析类型为null!");return null;}try {LOCK.lock();Object res = xPath.evaluate(xPathStr, doc, qName);return res;} finally {// TODO: handle finally clauseLOCK.unlock();}} catch (Exception e) {log.warn("解析Xpath:{},出现错误,解析类型:{},错误原因:{}!", xPathStr, qName, e.getMessage());}return null;}/*** 根据ElementImpl得到Jsoup的Element* * @param elementImpl* @return*/public static org.jsoup.nodes.Element getJsoupEle(final ElementImpl elementImpl) {try {String value = getW3cDocString(elementImpl);org.jsoup.nodes.Document document = Jsoup.parse(value);return document.body().child(0);} catch (Exception e) {// TODO: handle exceptionlog.error("根据ElementImpl得到Jsoup的Element出现错误,错误原因:" + e.getMessage());return null;}}/*** 将w3c的Document转为jsoup的Document* * @param doc* @return*/public static org.jsoup.nodes.Document fromW3C(final Document doc) throws Exception {String string = getW3cDocString(doc);org.jsoup.nodes.Document res = Jsoup.parse(string);return res;}/*** 将jsoup的Document转为w3c的Document* * @param in* @return*/public static Node fromJsoup(final org.jsoup.nodes.Element in) {DocumentBuilder builder;try {if (null == in) {return null;}builder = factory.newDocumentBuilder();Document out = builder.newDocument();if (in instanceof org.jsoup.nodes.Document) {List<org.jsoup.nodes.Node> childs = in.childNodes();if (childs != null && childs.size() > 0) {org.jsoup.nodes.Element rootEl = in.child(0);NodeTraversor traversor = new NodeTraversor(new W3CBuilder(out));traversor.traverse(rootEl);return out;} else {// out.setNodeValue(in.);return out;}}else if (in instanceof org.jsoup.nodes.Element) {NodeTraversor traversor = new NodeTraversor(new W3CBuilder(out));traversor.traverse(in);return out;}} catch (ParserConfigurationException e) {return null;}return null;}/*** 将W3c的doc转为字符串* * @param doc* @return* @throws Exception*/public static String getW3cDocString(final Node doc) throws Exception {try (StringWriter writer = new StringWriter()) {DOMSource domSource = new DOMSource(doc);StreamResult result = new StreamResult(writer);LOCK.lock();try {Transformer transformer = tf.newTransformer();transformer.transform(domSource, result);return writer.toString();} finally {LOCK.unlock();}} catch (TransformerException e) {throw new IllegalStateException(e);}}/*** 将Jsoup的node属性拷贝到w3c的Element中* * @param source* @param el*/public static void copyAttributes(final org.jsoup.nodes.Node source, final Element el) {for (Attribute attribute : source.attributes()) {el.setAttribute(attribute.getKey(), attribute.getValue());}}}class W3CBuilder implements NodeVisitor {private final Document doc;private Element dest;public W3CBuilder(Document doc) {this.doc = doc;}public void head(final org.jsoup.nodes.Node source, int depth) {if (source instanceof org.jsoup.nodes.Element) {org.jsoup.nodes.Element sourceEl = (org.jsoup.nodes.Element) source;Element el = doc.createElement(sourceEl.tagName());JsoupParserUtils.copyAttributes(sourceEl, el);if (dest == null) {doc.appendChild(el);} else {dest.appendChild(el);}dest = el;} else if (source instanceof org.jsoup.nodes.TextNode) {org.jsoup.nodes.TextNode sourceText = (org.jsoup.nodes.TextNode) source;Text text = doc.createTextNode(sourceText.getWholeText());dest.appendChild(text);} else if (source instanceof org.jsoup.nodes.Comment) {org.jsoup.nodes.Comment sourceComment = (org.jsoup.nodes.Comment) source;Comment comment = doc.createComment(sourceComment.getData());dest.appendChild(comment);} else if (source instanceof org.jsoup.nodes.DataNode) {org.jsoup.nodes.DataNode sourceData = (org.jsoup.nodes.DataNode) source;Text node = doc.createTextNode(sourceData.getWholeData());dest.appendChild(node);} else {}}public void tail(final org.jsoup.nodes.Node source, int depth) {if (source instanceof org.jsoup.nodes.Element && dest.getParentNode() instanceof Element) {dest = (Element) dest.getParentNode();}}
}
  • CharsetDetecor.java  用于字符集检测的方法。
/** Copyright (C) 2014 hu** This program is free software; you can redistribute it and/or* modify it under the terms of the GNU General Public License* as published by the Free Software Foundation; either version 2* of the License, or (at your option) any later version.** This program is distributed in the hope that it will be useful,* but WITHOUT ANY WARRANTY; without even the implied warranty of* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the* GNU General Public License for more details.** You should have received a copy of the GNU General Public License* along with this program; if not, write to the Free Software* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.*/
package com.etoak.crawl.util;import org.mozilla.universalchardet.UniversalDetector;import java.io.UnsupportedEncodingException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;/*** 字符集自动检测** @author hu*/
public class CharsetDetector {//从Nutch借鉴的网页编码检测代码private static final int CHUNK_SIZE = 2000;private static Pattern metaPattern = Pattern.compile("<meta\\s+([^>]*http-equiv=(\"|')?content-type(\"|')?[^>]*)>",Pattern.CASE_INSENSITIVE);private static Pattern charsetPattern = Pattern.compile("charset=\\s*([a-z][_\\-0-9a-z]*)", Pattern.CASE_INSENSITIVE);private static Pattern charsetPatternHTML5 = Pattern.compile("<meta\\s+charset\\s*=\\s*[\"']?([a-z][_\\-0-9a-z]*)[^>]*>",Pattern.CASE_INSENSITIVE);//从Nutch借鉴的网页编码检测代码private static String guessEncodingByNutch(byte[] content) {int length = Math.min(content.length, CHUNK_SIZE);String str = "";try {str = new String(content, "ascii");} catch (UnsupportedEncodingException e) {return null;}Matcher metaMatcher = metaPattern.matcher(str);String encoding = null;if (metaMatcher.find()) {Matcher charsetMatcher = charsetPattern.matcher(metaMatcher.group(1));if (charsetMatcher.find()) {encoding = new String(charsetMatcher.group(1));}}if (encoding == null) {metaMatcher = charsetPatternHTML5.matcher(str);if (metaMatcher.find()) {encoding = new String(metaMatcher.group(1));}}if (encoding == null) {if (length >= 3 && content[0] == (byte) 0xEF&& content[1] == (byte) 0xBB && content[2] == (byte) 0xBF) {encoding = "UTF-8";} else if (length >= 2) {if (content[0] == (byte) 0xFF && content[1] == (byte) 0xFE) {encoding = "UTF-16LE";} else if (content[0] == (byte) 0xFE&& content[1] == (byte) 0xFF) {encoding = "UTF-16BE";}}}return encoding;}/*** 根据字节数组,猜测可能的字符集,如果检测失败,返回utf-8** @param bytes 待检测的字节数组* @return 可能的字符集,如果检测失败,返回utf-8*/public static String guessEncodingByMozilla(byte[] bytes) {String DEFAULT_ENCODING = "UTF-8";UniversalDetector detector = new UniversalDetector(null);detector.handleData(bytes, 0, bytes.length);detector.dataEnd();String encoding = detector.getDetectedCharset();detector.reset();if (encoding == null) {encoding = DEFAULT_ENCODING;}return encoding;}/*** 根据字节数组,猜测可能的字符集,如果检测失败,返回utf-8* @param content 待检测的字节数组* @return 可能的字符集,如果检测失败,返回utf-8*/public static String guessEncoding(byte[] content) {String encoding;try {encoding = guessEncodingByNutch(content);} catch (Exception ex) {return guessEncodingByMozilla(content);}if (encoding == null) {encoding = guessEncodingByMozilla(content);return encoding;} else {return encoding;}}
}

 

  • page.java 页面读取后返回的对象 

 

package com.etoak.crawl.page;import com.etoak.crawl.util.CharsetDetector;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;import java.io.UnsupportedEncodingException;/*
* page
*   1: 保存获取到的响应的相关内容;
* */
public class Page {private byte[] content ;private String html ;  //网页源码字符串private Document doc  ;//网页Dom文档private String charset ;//字符编码private String url ;//url路径private String contentType ;// 内容类型public Page(byte[] content , String url , String contentType){this.content = content ;this.url = url ;this.contentType = contentType ;}public String getCharset() {return charset;}public String getUrl(){return url ;}public String getContentType(){ return contentType ;}public byte[] getContent(){ return content ;}/*** 返回网页的源码字符串** @return 网页的源码字符串*/public String getHtml() {if (html != null) {return html;}if (content == null) {return null;}if(charset==null){charset = CharsetDetector.guessEncoding(content); // 根据内容来猜测 字符编码}try {this.html = new String(content, charset);return html;} catch (UnsupportedEncodingException ex) {ex.printStackTrace();return null;}}/**  得到文档* */public Document getDoc(){if (doc != null) {return doc;}try {this.doc = Jsoup.parse(getHtml(), url);return doc;} catch (Exception ex) {ex.printStackTrace();return null;}}}

 

  • sendRequstAndGetResponse.java发送url请求的类
     要注意我在//zz之中加了请求头,否则你爬取许许多多的网站都不行。
    package com.etoak.crawl.page;import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler;
    import org.apache.commons.httpclient.HttpClient;
    import org.apache.commons.httpclient.HttpException;
    import org.apache.commons.httpclient.HttpStatus;
    import org.apache.commons.httpclient.methods.GetMethod;
    import org.apache.commons.httpclient.params.HttpMethodParams;import java.io.IOException;public class RequestAndResponseTool {public static Page  sendRequstAndGetResponse(String url) {Page page = null;// 1.生成 HttpClinet 对象并设置参数HttpClient httpClient = new HttpClient();// 设置 HTTP 连接超时 5shttpClient.getHttpConnectionManager().getParams().setConnectionTimeout(5000);// 2.生成 GetMethod 对象并设置参数GetMethod getMethod = new GetMethod(url);//zz设置请求头getMethod.setRequestHeader("user-agent","Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.139 Safari/537.36");//zz设置编码格式Content-Encoding →gzip//getMethod.setRequestHeader("Content-Encoding","GBKs");// 设置 get 请求超时 5sgetMethod.getParams().setParameter(HttpMethodParams.SO_TIMEOUT, 5000);// 设置请求重试处理getMethod.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler());// 3.执行 HTTP GET 请求try {int statusCode = httpClient.executeMethod(getMethod);// 判断访问的状态码if (statusCode != HttpStatus.SC_OK) {System.err.println("Method failed: " + getMethod.getStatusLine());}// 4.处理 HTTP 响应内容byte[] responseBody = getMethod.getResponseBody();// 读取为字节 数组String contentType = getMethod.getResponseHeader("Content-Type").getValue(); // 得到当前返回类型page = new Page(responseBody,url,contentType); //封装成为页面} catch (HttpException e) {// 发生致命的异常,可能是协议不对或者返回的内容有问题System.out.println("Please check your provided http address!");e.printStackTrace();} catch (IOException e) {// 发生网络异常e.printStackTrace();} finally {// 释放连接getMethod.releaseConnection();}return page;}
    }
    

     

  •  写主方法测试一下
package com.etoak.crawl.main;import com.etoak.crawl.page.Page;
import com.etoak.crawl.page.RequestAndResponseTool;
import com.etoak.crawl.util.JsoupParserUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;import java.util.List;/*** Too young too simple,sometimes naive** @author zhang zhuang* @E-mail 418665906@qq.com* @Date 2019/3/30 20:07*/
public class sadas {public static void main(String[] args) throws Exception {Page page = RequestAndResponseTool.sendRequstAndGetResponse("https://search.jd.com/Search?keyword=%E6%89%8B%E6%9C%BA&enc=utf-8&wq=s&pvid=7e72beb42fbe499aa4d76b684082477d");Document doc = Jsoup.parse(page.getHtml());System.out.println(doc.body());Element element = JsoupParserUtils.getJsoupElement(doc, "");}
}

结果:

下面开始写一些爬取的技巧。

我的开发方法:

1、首先找到url的规律,你要爬取数据肯定一连串的爬取,像我以前为了更新自己做的电商项目的数据库就爬取了京东的数据一千多条如下图:

都是看url来的,举个栗子:

https://search.jd.com/Search?keyword=%E6%89%8B%E6%9C%BA&enc=utf-8&qrst=1&rt=1&stop=1&vt=2&wq=s&cid2=653&cid3=655&page=3&s=57&click=0

京东的get方法获取的里面的参数都是有用的,keyword不用说就是搜索的时候关键字,utf-8这都不要说,page要说就是第几页的意思,但是我点的是第二页它为什么会显示第三页,候取在浏览一下就知道了因为它动态加载了,s我观察的一段时间发现他是一页商品的数量,这样不久明了了,我于是我就把url写成这样来避免动态加载, 'https://search.jd.com/Search?keyword=%E8%A1%A3%E6%9C%8D&enc=utf-8&qrst=1&rt=1&stop=1&vt=2&stock=1&page='+str(n)+'&s='+str(1+(n-1)*30)+'&click=0&scrolling=y'

其中n表示第几页然后s表示曾经一页表示的商品数量,因为我观察了,点击第一页其实它已经动态加载了第二页,那么我通过修改s发现可以不让他加载。

2、拆分你自己爬到的网站,原则是先选择一个大模块(涵盖你需要的所有数据),然后再次一个个遍历。

举个栗子:

看到这张图片没,我需要的是 这个模块的所有信息,那么我先选这个模块的上一个模块,因为上一个模块包含了这一页所有的商品,然后接着

List<Element> element = JsoupParserUtils.getJsoupElements(doc, "你自己的xpath");通过遍历list数组方法来获取进一步xpath来获取每一商品模块信息。

3、技巧刚刚如果你仔细观察图片你应该发现我用了一个工具,这个工具是谷歌浏览器插件叫做xpath,自己翻墙下载一下,但是我要提醒你一句,这上面给的xpath是不太正确的,因为它给你的是浏览器的解析到的html,所以你必须自己通过

System.out.println(page.getHtml());

查看你自己爬到的html,然后进行修改才能获取到你想要的信息。

(2)还要注意一点有的网页比如淘宝,你爬取的内容数据都在script里面的一个json

通过

List<Element> elements1 = doc.getElementsByTag("script");
Elements e = doc.getElementsByTag("script").eq(7);

获取script的数据,然后解析json,至于如何解析自己查。

 

 

 

 

 

 

 

 

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_893071.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

.NET小实例——构建一个购物网站

步骤如下&#xff1a; 一、先在VS2015中建一个项目Shopping 二、新建相关的Controller和Model和View 1.在Controllers文件夹中新建一个ShoppingController.cs &#xff08;注意这个地方命名时只能改前面的部分&#xff0c;后面的Controller是不能改的&#xff09; 2.在Models…

solr 对网站域名的搜索技巧应用

菜鸟级文章,高手请绕道. 基本事情背景是这样, 在公司的抓取回来的数据中,都有大量的来源不同网站的域名.这时用户可能只对某几个来源网站感兴趣,或者对某几个来源网站不感兴趣之类,以前的版本中,只对网站域名做了非常简单的分词,基本上可以认为是对 www.it.com.cn 之类的网站,通…

如何做公众号SEO,公众号排名优化呢?

SEO也就是搜索引擎优化&#xff0c;简单点说就是搜索排名优化。也就是当用户搜索某一些关键词时&#xff0c;就会看到你的文章或者帐号排在前几位&#xff0c;做SEO其实就是为了提高排名&#xff0c;获取精准垂直流量。 要做公众号排名首先要知道两个重点&#xff0c;一是关键词…

大型网站架构演化发展历程

1.大型网站软件系统的特点 与传统企业应用系统相比&#xff0c;大型互联网应用系统有以下特点。 &#xff08;1&#xff09;高并发&#xff0c;大流量&#xff1b;&#xff08;2&#xff09;高可用&#xff1b;&#xff08;3&#xff09;海量数据&#xff1b;&#xff08;4&a…

大型网站架构技术一览

网站系统架构层次如下图所示&#xff1a; 1.前端架构 浏览器优化技术、CDN、动静分离、静态资源独立部署、图片服务、反向代理、DNS。 2.应用层架构 开发框架、页面渲染、负载均衡、Session管理、动态页面静态化、业务拆分、虚拟化服务。 3.服务层架构 分布式消息、分布式服务、…

2-13 搭建LAMP环境并部署Ucenter和Ucenter-home网站

环境: VMware Virtual Machine : XGan63.cn IP: 192.168.31.63 (Bridge) 已配置本地yum源 ---> /mnt 已配置网络yum源 ---> http://mirrors.aliyun.com 安装前确保环境干净,避免软件冲突造成影响 检查环境: which httpd #查看是否安装httpd服务 chkconfig --list httpd…

大型网站架构心得之一:分

我们知道&#xff0c;对于一个大型网站来说&#xff0c;可伸缩性是非常重要的&#xff0c;怎么样在纵向和横向有良好的可伸缩性&#xff0c;就需要在做架构设计的时候考虑到一个分的原则&#xff0c;我想在多个方面说一下怎么分&#xff1a; 首先是横向的分&#xff1a; 1…

PC文件在线互传网站推荐

大文件&#xff1a; U盘或者移动硬盘才是首选&#xff0c;没有条件才用此下策 轻松传 - 传文件&#xff0c;传文本&#xff0c;传屏幕&#xff0c;传实时视频https://easychuan.cn/ 无需上传&#xff0c;直接下载&#xff0c;这是它的优点。使用edge亲身体验有个bug&…

IE浏览器提示网站还原错误

win 10 系统IE(Internet Explorer)浏览器提示网站还原错误&#xff0c;报错图如下 &#xff1a; 网上找了很多的方法&#xff0c;重置浏览器设置&#xff0c;降低自定义安全级别&#xff0c;添加受信任站点、禁用加载项、清除历史缓存记录等皆无用。 一、解决方法 1.此电脑--…

Java web 小白学习日记(4)—— 本地端的第一个网站

本篇内容续 小白日记&#xff08;3&#xff09; 本地端的第一个网站 目录 1&#xff09;web工程的创建&#xff0c;如下图 2&#xff09;若要调入图片&#xff0c;在本地找到该工程的工作空间&#xff0c;在WebRoot目录下创建images目录&#xff08;默认名为images&#xff…

Java web 学习日记(5)——云服务器端的第一个网站

本篇内容续 小白日记&#xff08;4&#xff09; 也可直接食用 云服务器端的第一个网站 目录 1&#xff09;选中我们要使用的web工程&#xff0c;点击file菜单中的export 2&#xff09;选择Java EE 中的 WAR包格式&#xff0c;点击next 3&#xff09;步骤如图 4&#xff0…

linux云服务器部署springboot网站 jar包部署过程

首先对我们的项目进行打包&#xff0c;可以直接输入命令 mvn clean package 如果遇到过程test报错 可以选择右侧maven任务栏里的闪电图案&#xff0c;跳过test 使用filezilla连接我们的服务器&#xff0c;将jar包上传到指定文件夹 使用putty登录云服务器 一些命令介绍 cd /us…

java web项目部署云服务器实现外网访问网站

本文为学习经验分享&#xff0c;水平有限&#xff0c;若有问题还请多多包涵&#xff0c;多多交流。 目录 一、租用云服务器 二、配置云服务器 三、Mysql安装与配置 四、JDK的安装&#xff08;重要&#xff09; 五、Tomcat 的安装与部属&#xff08;重点&#xff09; 六、…

VS 发布网站的配置

此配置发布为已经编译的网站&#xff0c;并且不可查看源代码。 &#xfeff;&#xfeff;

一个图标下载网站(自用)

地址&#xff1a;http://www.iconfont.cn/collections/detail?cid29

国外免费Icon图标下载网站大全(共55个网站)

Icon 图标通常应用于对系统的美化和应用程序的UI设计中。但是随着Web2.0的大潮兴起&#xff0c;大而醒目的设计元素也日趋流行。你完全可以把图标应用到网站设计 中&#xff0c;比如菜单栏图标、分类图标等。现在&#xff0c;帕兰映像为你收集整理了下面50多个国外的免费Icon图…

14个超棒的带有故事趣味性视差滚动网站

随着css3属性的广泛支持&#xff0c;越来越被设计师所青昧 &#xff0c;常常可以创造出惊人的网站作品出来&#xff0c;特别是视差滚动的出色表现。关于视差滚动在实现方面&#xff0c;在之前的文章中《利用JARALLAX实现超强视差滚动网页效果》也为大家介绍了一个小插件的实现方…

Asp.net 2.0 中将网站首页生成静态页的一个比较好的方法

做网站时,有时为了提高性能会将网站首页生成静态页(当然, Asp.net中页面缓存也是一个不错的选择了将页面生成静态的方法有多中,据不完全统计有N种(N>1)呵呵以下的方法来自 "孟子E " 解释的方法 代码如下 protected override void Render(HtmlTextWriter writer) …

抓取一个网站特定的全部图片(JAVA)

1. 目的 用五笔时&#xff0c;如果碰到不会拆的字&#xff0c;只好换回拼音。但这样做治标不治本&#xff0c;于是到网上找五笔反查工具。最后发现一个不错的网站——不仅有每个字对应的五笔码&#xff0c;还有其字根图。可惜的是&#xff0c;这是一个网站。换句说&#xff0c;…

轻松完成网站提速:来自Google、淘宝等的Nginx PageSpeed模块

mod_pagespeed于2010年发布&#xff0c;让网站管理员可以为其Web应用提速&#xff0c;而不需要深度的性能优化造诣。mod_pagespeed最初版本只作为Apache的模块&#xff0c;并不兼容Nginx这个最流行并为许多大型站点所使用的高性能开源网络服务器。如今Nginx的PageSpeed Beta版终…