1. 程式人生 > >爬蟲配置必備:JQuery|querySelector|Cheerio DOM節點選擇乾貨集

爬蟲配置必備:JQuery|querySelector|Cheerio DOM節點選擇乾貨集

作者:fbysss

QQ:溜酒酒吧酒吧吾散

blog:blog.csdn.net/fbysss

宣告:本文由fbysss原創,轉載請註明出處

前言

網頁爬取,是一項既費腦子又繁瑣的工作。因為網頁格式不一,很難完全靠機器自動識別。

通常,我們可以採用css選擇器來選取DOM節點,從整個網頁中抽取我們需要的內容。

前端大家最熟悉的應該是JQuery了。如果JQuery不好用,可以直接使用原生的document.querySelectorAll,現在的瀏覽器大多也都支援了。

如果是Nodejs爬蟲,一般採用cheerio模組(可以理解為後端的JQuery)來解析DOM。

cheerio雖然高仿JQuery,但還是有些差異,而且一些特性尚未實現。儘量更新到最新版本。

這裡並不羅列所有的表示式,而是重點記錄一些DOM選擇和相關工作方法。

前端的例子中也都是cheerio都支援的表示式,測試環境都是chrome。

表示式

1.簡單表示式

document.querySelectorAll("div");//標籤
document.querySelectorAll(".classA");//單個類
document.querySelectorAll("#idA");//id選擇器

2.層級關係

document.querySelectorAll("div span");
document.querySelectorAll("div span .classA");

3.多個類

<div class="classA classB">
document.querySelectorAll(".classA.classB");
document.querySelectorAll("class=['classA classB']");//中括號中如果有空格,必須加引號

4.多選(or關係)

<div class="classA">
<div class="classB">
document.querySelectorAll(".classA,.classB");
<div id="#article">
<div class="description">

"#article,.description"不行,cheerio中只能使用".description,#article"

5.下一個元素

document.querySelectorAll.('h1+figure')  //選擇h1後面的figure元素

6.有特殊符號

<div class="tw:classA">
document.querySelectorAll("div[class=tw:classA]");

7.萬用字元

document.querySelectorAll("input[id^='code']");//id屬性以code開始的所有input標籤
document.querySelectorAll("input[id$='code']");//id屬性以code結束的所有input標籤
document.querySelectorAll("input[id*='code']");//id屬性包含code的所有input標籤


8.不等於

document.querySelectorAll("div:not([id^=\"blog\"])");//不等於

cheerio示例:

var cheerio=require("cheerio");
var str='<div class=redColor>fbysss</div> <div class=blueColor></div> <div class=yellowColor></div> <div class=normal></div>';
var $=cheerio.load(str);
var len = $("div:not([class$=\"Color\"])").length;
console.log("len is :",len);
9.忽略大小寫

還以上面的例子

var len = $("div:not([class$=\"Color\"])").length;更換為

var len = $("div:not([class$=\"color\" i])").length;即可。——\為轉義字元,當多層巢狀,單引號雙引號都用盡的時候需要

參考:

http://stackoverflow.com/questions/5671238/css-selector-case-insensitive-for-attributes

10.選擇文字節點

$(elem)
  .contents()
  .filter(function() {
    return this.nodeType === 3; //Node.TEXT_NODE
  });

11.選擇註釋節點

var cheerio = require('cheerio');
var str ="<img class='classA' length='80' width='100'/> <!--comment node text--> <span><!--comment in span--><ul><!--comment in ul--></ul></span>  <!--comment node 2--> <img class='classB'>";
var $ = cheerio.load(str);
$.root().find('*').contents().filter(function(){  return this.nodeType == 8;}).length;//注意,這裡是2
var str2 = "<div id='domRoot'>"+str+"</div>";
$ = cheerio.load(str2);
$.root().find('*').contents().filter(function(){  return this.nodeType == 8;}).length;//4.如果要刪除所有的註釋節點,需要在字串前面新增一個根節點
$.root().find(*)也可以直接使用$(*)

12.chrome中顯示的問題:

在最新的chrome版本中,console的顯示出現了變化。選擇一個節點,如果使用document.querySelectorAll,返回一個節點時,需要使用[0]才行,否則就是返回一個很大的節點,很不直觀。比如:document.querySelectorAll("div")[0]


對於多個節點,只能這麼寫了:

var cates = document.querySelectorAll('.article-title-link');
[].forEach.call(cates,function(cate){console.log(cate.href)}) 或者[].forEach.call(cates,function(cate){console.log(cate)})


還有更好的寫法:
document.querySelectorAll('.article-title-link').forEach(function(cate){console.log(cate)})

其他遇到的問題解決:

1.chrome突然怎麼都打不出東西來了。原來是一個選項的問題。在上方,勾選all,原來選擇了error所以不顯示。

2.JQuery:上述例子,前端都是以document.querySelectorAll、後端以cheerio舉例。

如果前端要使用JQuery,需要注意,有的網站可以,有的則不行,這和瀏覽器支援的JQuery版本、不同網站引用的JQuery版本有關。

如果出現無法選擇的情況,可以先在console中測試:$().jquery可以檢查當前的jquery版本

嘗試執行以下程式碼:

var jq = document.createElement('script');
jq.src = "http://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js";
document.getElementsByTagName('head')[0].appendChild(jq);
jQuery.noConflict();
對於https網頁,需要把http修改為https否則可能報錯: VM273:4 Mixed Content: The page at 'https://countrycode.org/' was loaded over HTTPS, but requested an insecure script 'http://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js'. This request has been blocked; the content must be served over HTTPS. 

結語

上面都是本人在爬蟲配置過程中,總結的經驗,相信對於從事網頁抓取工作的同學,會有很好的幫助。