整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          使用requests爬蟲「中文亂碼」的解決方法

          使用requests爬蟲「中文亂碼」的解決方法

          equests是一個較為簡單易用的HTTP請求庫,是python中編寫爬蟲程序最基礎常用的一個庫。對于初學者來說采集的數據【中文亂碼】問題是很煩惱的。

          本文將根據實踐經驗說明python中使用requests庫編寫爬蟲程序時,出現【中文亂碼】的原因及解決辦法。

          首先,本文的【中文亂碼】情況,指的是原網頁中的中文內容在使用requests獲取后,中文完全無法識別的情況,區別于\x、\u等編碼情況。如下圖中的例子:

          導致上圖中【中文亂碼】的原因:

          使用requests庫時,選擇使用的文本響應方法不合適,且沒有在代碼中添加設置合適的編碼,以致于使用【response.text】自動獲取到的網頁編碼,與實際網頁的編碼不一致,進而產生【中文亂碼】。

          使用requests庫時,可能已經形成了一個習慣,常用【response.text】進行文本響應,而【response.content】常用于圖片、視頻等。

          這兩者,最大的一個區別就是:

          1、【response.text】會自動根據HTTP頭部去推測網頁的編碼,解碼并返回解碼后的文本。

          2、【response.content】不會解碼,直接以二進制形式返回。

          兩種文本響應方法,如下表:

          response.text

          服務器響應的內容,會自動根據響應頭部的字符編碼進行解碼。根據HTTP頭部對響應的編碼做出有根據的推測,推測文本編碼。返回類型:str;常用于:響應文本

          response.content

          字節方式的響應體,不會根據HTTP頭部對響應的編碼做出有根據的推測。返回類型:bytes(二進制);常用于:圖片、視頻

          最有效的解決方法:

          獲取網頁編碼、指定其編碼,再提取文本

          使用response的encoding、apparent_encoding,得到網頁編碼。

          encoding、apparent_encoding兩者最大的區別:

          encoding是從header中去提取,而apparent_encoding是從網頁源碼去解析,apparent_encoding得到的結果更準確。

          詳細如下表:

          response.encoding

          從網頁響應的header中,提取charset字段中的編碼。若header中沒有charset字段,則默認為ISO-8859-1編碼模式,ISO-8859-1編碼無法解析中文,這也是中文亂碼的原因。

          response.apparent_encoding

          從網頁的內容中(html源碼)中分析網頁編碼的方式。所以apparent_encoding比encoding更加準確,獲取到的才是原網頁的實際編碼。

          print(response.apparent_encoding)
          print(response.encoding)

          使用encoding、apparent_encoding兩種方法,所得的結果是不一致的,apparent_encoding才是原網頁實際編碼。如下圖

          根據上述方法,獲得原網頁的實際編碼后,手動在代碼中指定文本編碼格式,即可解決【中文亂碼】問題。如下圖:

          response.encoding=response.apparent_encoding

          以上就是使用requests爬蟲解決中文亂碼的方法,如那位老師有更好的方法還望賜教,謝謝!

          符串作為基本的信息交流的橋梁,幾乎被所有的編程語言所實現(然而c、c++沒有提供)。多數開發者幾乎每天都在和字符串打交道,語言內置的String模塊,極大地提升了開發者的效率。JavaScript通過自動裝箱字符串字面量為String對象,自然地繼承了String.prototype的所有方法,更加簡化了字符串的使用。

          截止ES6,字符串共包含31個標準的API方法,其中有些方法出鏡率較高,需要摸透原理;有些方法之間相似度較高,需要仔細分辨;甚至有些方法執行效率較低,應當盡量少的使用。下面將從String構造器方法說起,逐步幫助你掌握字符串

          String構造器方法

          fromCharCode

          fromCharCode() 方法返回使用指定的Unicode序列創建的字符串,也就是說傳入Unicode序列,返回基于此創建的字符串。

          語法:fromCharCode(num1, num2,…),傳入的參數均為數字。

          如下這是一個簡單的例子,將返回 ABC、abc、*、+、- 和 /:

          String.fromCharCode(65, 66, 67); // "ABC"
          String.fromCharCode(97, 98, 99); // "abc"
          String.fromCharCode(42); // "*"
          String.fromCharCode(43); // "+"
          String.fromCharCode(45); // "-"
          String.fromCharCode(47); // "/"
          

          看起來fromCharCode像是滿足了需求,但實際上由于js語言設計時的先天不足(只能處理UCS-2編碼,即所有字符都是2個字節,無法處理4字節字符),通過該方法并不能返回一個4字節的字符,為了彌補這個缺陷,ES6新增了fromCodePoint方法

          fromCodePoint(ES6)

          fromCodePoint() 方法基于ECMAScript 2015(ES6)規范,作用和語法同fromCharCode方法,該方法主要擴展了對4字節字符的支持。

          // "" 是一個4字節字符,我們先看下它的數字形式
          "".codePointAt(); // 119558
          //調用fromCharCode解析之,返回亂碼
          String.fromCharCode(119558); // "?"
          //調用fromCodePoint解析之,正常解析
          String.fromCodePoint(119558); // ""
          

          除了擴展對4字節的支持外,fromCodePoint還規范了錯誤處理,只要是無效的Unicode編碼,就會拋出錯誤RangeError: Invalid code point...,這就意味著,只要不是符合Unicode字符范圍的正整數(Unicode最多可容納1114112個碼位),均會拋出錯誤,而String.fromCharCode()均返回空字符串

          String.fromCodePoint('abc'); // RangeError: Invalid code point NaN
          String.fromCodePoint(Infinity); // RangeError: Invalid code point Infinity
          String.fromCodePoint(-1.23); // RangeError: Invalid code point -1.23
          

          raw(ES6)

          raw() 方法基于ECMAScript 2015(ES6)規范,它是一個模板字符串的標簽函數,作用類似于Python的r和C#的@字符串前綴,都是用來獲取一個模板字符串的原始字面量。

          語法: String.raw(callSite, …substitutions),callSite即模板字符串的『調用點對象』,…substitutions表示任意個內插表達式對應的值,這里理解起來相當拗口,下面我將通俗的講解它。

          // 防止特殊字符串被轉義
          String.raw`a\nb\tc`; // 輸出為 "a\nb\tc"
          // 支持內插表達式
          let name="louis";
          String.raw`Hello \n ${name}`; // "Hello \n louis"
          // 內插表達式還可以運算
          String.raw`1+2=${1+2},2*3=${2*3}`; // "1+2=3,2*3=6"
          // 對象的raw屬性值為字符串時,從第二個參數起,它們分別被插入到下標為0,1,2,...n的元素后面
          String.raw({raw: 'abcd'}, 1, 2, 3); // "a1b2c3d"
          // 對象的raw屬性值為數組時,從第二個參數起,它們分別被插入到數組下標為0,1,2,...n的元素后面
          String.raw({raw: ['a', 'b', 'c', 'd']}, 1, 2, 3); // "a1b2c3d"
          

          那么怎么解釋String.raw函數按照下標挨個去插入的特性呢?

          In most cases, String.raw() is used with template strings. The first syntax mentioned above is only rarely used, because the JavaScript engine will call this with proper arguments for you, just like with other tag functions.

          這意味著,String.raw作為函數調用時,基本與ES6的tag標簽模板一樣

          // 如下是tag函數的實現
          function tag(){
           const array=arguments[0];
           return array.reduce((p, v, i)=> p + (arguments[i] || '') + v);
          }
          // 回顧一個simple的tag標簽模板
          tag`Hello ${ 2 + 3 } world ${ 2 * 3 }`; // "Hello 5 world 6"
          // 其實就想當于如下調用
          tag(['Hello ', ' world ', ''], 5, 6); // "Hello 5 world 6"
          

          因此String.raw作為函數調用時,不論對象的raw屬性值是字符串還是數組,插槽都是天生的,下標為0,1,2,…n的元素后面都是插槽(不包括最后一個元素)。實際上,它相當于是這樣的tag函數:

          function tag(){
           const array=arguments[0].raw;
           if(array===undefined || array===null){ // 這里可簡寫成 array==undefined
           throw new TypeError('Cannot convert undefined or null to object');
           }
           return array.reduce((p, v, i)=> p + (arguments[i] || '') + v);
          }
          

          實際上,String.raw作為函數調用時,若第一個參數不是一個符合標準格式的對象,執行將拋出TypeError錯誤。

          String.raw({123: 'abcd'}, 1, 2, 3); // TypeError: Cannot convert undefined or null to object
          

          String.prototype

          和其他所有對象一樣,字符串實例的所有方法均來自String.prototype。以下是它的屬性特性:

          writable: false

          enumerable: false

          configurable: false

          可見,字符串屬性不可編輯,任何試圖改變它屬性的行為都將拋出錯誤。

          屬性

          String.prototype共有兩個屬性,如下:

          • String.prototype.constructor 指向構造器(String())
          • String.prototype.length 表示字符串長度

          方法

          字符串原型方法分為兩種,一種是html無關的方法,一種是html有關的方法。我們先看第一種。但是無論字符串方法如何厲害,都不至于強大到可以改變原字符串。

          HTML無關的方法

          常用的方法有,charAt、charCodeAt、concat、indexOf、lastIndexOf、localeCompare、match、replace、search、slice、split、substr、substring、toLocaleLowerCase、toLocaleUpperCase、toLowerCase、toString、toUpperCase、trim、valueof 等ES5支持的,以及 codePointAt、contains、endsWith、normalize、repeat、startsWith 等ES6支持的,還包括 quote、toSource、trimLeft、trimRight 等非標準的。

          接下來我們將對各個方法分別舉例闡述其用法。若沒有特別說明,默認該方法兼容所有目前主流瀏覽器。

          charAt

          charAt() 方法返回字符串中指定位置的字符。

          語法:str.charAt(index)

          index 為字符串索引(取值從0至length-1),如果超出該范圍,則返回空串

          console.log("Hello, World".charAt(8)); // o, 返回下標為8的字符串o
          

          charCodeAt

          charCodeAt() 返回指定索引處字符的 Unicode 數值。

          語法:str.charCodeAt(index)

          index 為一個從0至length-1的整數。如果不是一個數值,則默認為 0,如果小于0或者大于字符串長度,則返回 NaN。

          Unicode 編碼單元(code points)的范圍從 0 到 1,114,111。開頭的 128 個 Unicode 編碼單元和 ASCII 字符編碼一樣.

          charCodeAt() 總是返回一個小于 65,536 的值。因為高位編碼單元需要由一對字符來表示,為了查看其編碼的完成字符,需要查看 charCodeAt(i) 以及 charCodeAt(i+1)

          console.log("Hello, World".charCodeAt(8)); // 111
          console.log("前端工程師".charCodeAt(2)); // 24037, 可見也可以查看中文Unicode編碼
          

          concat

          concat() 方法將一個或多個字符串拼接在一起,組成新的字符串并返回。

          語法:str.concat(string2, string3, …)

          console.log("早".concat("上","好")); // 早上好 1

          但是 concat 的性能表現不佳,強烈推薦使用賦值操作符(+或+=)代替 concat。”+” 操作符大概快了 concat 幾十倍。

          indexOf 和 lastIndexOf

          indexOf() 方法用于查找子字符串在字符串中首次出現的位置,沒有則返回 -1。該方法嚴格區分大小寫,并且從左往右查找。而 lastIndexOf 則從右往左查找,其它與前者一致。

          語法:str.indexOf(searchValue [, fromIndex=0]),str.lastIndexOf(searchValue [, fromIndex=0])

          searchValue 表示被查找的字符串,fromIndex 表示開始查找的位置,默認為0,如果小于0,則查找整個字符串,若超過字符串長度,則該方法返回-1,除非被查找的是空字符串,此時返回字符串長度。

          console.log("".indexOf("",100)); // 0
          console.log("IT改變世界".indexOf("世界")); // 4
          console.log("IT改變世界".lastIndexOf("世界")); // 4
          

          localeCompare

          localeCompare() 方法用來比較字符串,如果指定字符串在原字符串的前面則返回負數,否則返回正數或0,其中0 表示兩個字符串相同。該方法實現依賴具體的本地實現,不同的語言下可能有不同的返回。

          語法:str.localeCompare(str2 [, locales [, options]])

          var str="apple";
          var str2="orange";
          console.log(str.localeCompare(str2)); // -1
          console.log(str.localeCompare("123")); // 1
          

          match

          match() 方法用于測試字符串是否支持指定正則表達式的規則,即使傳入的是非正則表達式對象,它也會隱式地使用new RegExp(obj)將其轉換為正則表達式對象。

          語法:str.match(regexp)

          該方法返回包含匹配結果的數組,如果沒有匹配項,則返回 null。

          描述

          • 若正則表達式沒有 g 標志,則返回同 RegExp.exec(str) 相同的結果。而且返回的數組擁有一個額外的 input 屬性,該屬性包含原始字符串,另外該數組還擁有一個 index 屬性,該屬性表示匹配字符串在原字符串中索引(從0開始)。
          • 若正則表達式包含 g 標志,則該方法返回一個包含所有匹配結果的數組,沒有匹配到則返回 null。

          相關 RegExp 方法

          • 若需測試字符串是否匹配正則,請參考 RegExp.test(str)。
          • 若只需第一個匹配結果,請參考 RegExp.exec(str)。
          var str="World Internet Conference";
          console.log(str.match(/[a-d]/i)); // ["d", index: 4, input: "World Internet Conference"]
          console.log(str.match(/[a-d]/gi)); // ["d", "C", "c"]
          // RegExp 方法如下
          console.log(/[a-d]/gi.test(str)); // true
          console.log(/[a-d]/gi.exec(str)); // ["d", index: 4, input: "World Internet Conference"]
          

          由上可知,RegExp.test(str) 方法只要匹配到了一個字符也返回true。而RegExp.exec(str) 方法無論正則中有沒有包含 g 標志,RegExp.exec將直接返回第一個匹配結果,且該結果同 str.match(regexp) 方法不包含 g 標志時的返回一致。

          replace

          語法 str.replace( regexp | substr, newSubStr | function[, flags] )

          參數

          • regexp: 一個 RegExp 對象. 該正則所匹配的內容會被第二個參數的返回值替換掉。
          • substr: 一個要被 newSubStr 替換的字符串.
          • newSubStr: 替換掉第一個參數在原字符串中的匹配部分. 該字符串中可以內插一些特殊的變量名.
          • function: 一個用來創建新子字符串的函數, 該函數的返回值將替換掉第一個參數匹配到的結果. 該函數的參數描述請參考 指定一個函數作為參數 小節.
          • flags: 注意:flags 參數在 v8 內核(Chrome and NodeJs)中不起作用. 方法中使用 flags 參數不是符合標準的并且不贊成這樣做.

          簡單概括,replace擁有兩個參數,第一個是需要替換的字符串或者正則表達式;第二個是新的字符串或者一個function,這樣參數便有四種組合.

          該方法并不改變調用它的字符串本身,而只是返回替換后的字符串.

          var b=a.replace("before","after");
          console.log(b); // "what is this? after"
          

          如果第一個參數是正則表達式,新的字符串中可以用$符號取正則中匹配的子串(也就是正則中被括號包裹的部分):

          var a="what is this? before";
          var b=a.replace(/(^\w+).*?(\w+)$/,"$2 $1");//括號分割的部分依次為子串1....n
          console.log(b); // "before what"
          

          第二個參數其實可為一個function,最終字符串將以function的返回值作為replace的返回值,以下是該function的形參: function(match,p1…,offset,string),可見至少包含三個形參(即arguments.length>=3)

          • match表示第一個參數(整個正則表達式)匹配的字符串
          • p1至pn表示第1..n個括號匹配的字符串,如果沒有括號則不存在該項
          • offset表示匹配的起點在原字符串中的偏移
          • string表示原字符串
          function replacer(match,p1,p2,offset,string){
           //此時p1=" is",p2=" this"
           return p1+" that";//如果返回為空串,則匹配內容替換為空,如果不返回,則匹配內容替換為undefined
          }
          var a="what is this? before";
          var b=a.replace(/(\s\w+)(\s\w+)/,replacer);
          console.log(b); // "what is that? before"
          function replacer(match,offset,string){
           //由于字符串中不會有括號進行分組,此時沒有子串
           return offset+" that";//偏移為4
          }
          var a="what is this? before";
          var b=a.replace(" is this",replacer);
          console.log(b); // "what4 that? before"
          

          基于 replace 方法的第三個用法, 我們可以實現一個tmpl方法, 輸入一個模板字符串, 輸入一個key-value對象, 即可生成新的字符串.

          var template="one {a} two {b} {c}",
           obj={a:"apple",b:"orange",c:"..."},
           _array=[];
          function tmpl(template,obj){
           var retu=template.replace(/([^{}]*){(.)}/g,function(match,p1,p2,offset,string){
           _array.push({'match':match, 'p1':p1, 'p2':p2, 'offset':offset, 'string':string});
           return p1+obj[p2];
           });
           console.table && console.table(_array);
           !console.table && console.log(_array);
           console.log(retu);
          }
          tmpl(template,obj);
          

          .(小數點):匹配除換行符之外的任何單個字符。例如,/.n/將會匹配 "nay, an apple is on the tree" 中的 'an' 和 'on',但是不會匹配 'nay'。

          [^xyz]:一個反向字符集。也就是說, 它匹配任何沒有包含在方括號中的字符。你可以使用破折號(-)來指定一個字符范圍。任何普通字符在這里都是起作用的。例如,[^abc] 和 [^a-c] 是一樣的。他們匹配"brisket"中的‘r’,也匹配“chop”中的‘h’。

          search

          search() 方法用于測試字符串對象是否包含某個正則匹配,相當于正則表達式的 test 方法,且該方法比 match() 方法更快。如果匹配成功,search() 返回正則表達式在字符串中首次匹配項的索引,否則返回-1。

          注意:search方法與indexOf方法作用基本一致,都是查詢到了就返回子串第一次出現的下標,否則返回-1,唯一的區別就在于search默認會將子串轉化為正則表達式形式,而indexOf不做此處理,也不能處理正則

          語法:str.search(regexp)
          var str="abcdefg";
          console.log(str.search(/[d-g]/)); // 3, 匹配到子串"defg",而d在原字符串中的索引為3
          

          search() 方法不支持全局匹配(正則中包含g參數),如下:

          console.log(str.search(/[d-g]/g)); // 3, 與無g參數時,返回相同
          

          slice

          slice() 方法提取字符串的一部分,并返回新的字符串。該方法有些類似 Array.prototype.slice 方法。

          語法:str.slice(start, end)

          首先 end 參數可選,start可取正值,也可取負值。

          • 取正值時表示從索引為start的位置截取到end的位置(不包括end所在位置的字符,如果end省略則截取到字符串末尾)。
          • 取負值時表示從索引為 length+start 位置截取到end所在位置的字符
          var str="It is our choices that show what we truly are, far more than our abilities.";
          console.log(str.slice(0,-30)); // It is our choices that show what we truly are
          console.log(str.slice(-30)); // , far more than our abilities.
          

          split

          split() 方法把原字符串分割成子字符串組成數組,并返回該數組。

          語法:str.split(separator, limit)

          兩個參數均是可選的,其中 separator 表示分隔符,它可以是字符串也可以是正則表達式。如果忽略 separator,則返回的數組包含一個由原字符串組成的元素。如果 separator 是一個空串,則 str 將會被分割成一個由原字符串中字符組成的數組。limit 表示從返回的數組中截取前 limit 個元素,從而限定返回的數組長度。

          var str="today is a sunny day";
          console.log(str.split()); // ["today is a sunny day"]
          console.log(str.split("")); // ["t", "o", "d", "a", "y", " ", "i", "s", " ", "a", " ", "s", "u", "n", "n", "y", " ", "d", "a", "y"]
          console.log(str.split(" ")); // ["today", "is", "a", "sunny", "day"]
          

          使用limit限定返回的數組大小,如下:

          console.log(str.split(" ", 1)); // ["today"]
          console.log(str.split(/\s*is\s*/)); // ["today", "a sunny day"]
          // 若正則分隔符里包含捕獲括號,則括號匹配的結果將會包含在返回的數組中。
          console.log(str.split(/(\s*is\s*)/)); // ["today", " is ", "a sunny day"]
          

          substr

          substr() 方法返回字符串指定位置開始的指定數量的字符。

          語法:str.substr(start[, length])

          start 表示開始截取字符的位置,可取正值或負值。取正值時表示start位置的索引,取負值時表示 length+start位置的索引。

          length 表示截取的字符長度。

          var str="Yesterday is history. Tomorrow is mystery. But today is a gift.";
          console.log(str.substr(47)); // today is a gift.
          console.log(str.substr(-16)); // today is a gift.
          

          substring

          substring() 方法返回字符串兩個索引之間的子串。

          語法:str.substring(indexA[, indexB])

          indexA、indexB 表示字符串索引,其中 indexB 可選,如果省略,則表示返回從 indexA 到字符串末尾的子串。

          描述

          substring 要截取的是從 indexA 到 indexB(不包含)之間的字符,符合以下規律:

          • 若 indexA==indexB,則返回一個空字符串;
          • 若 省略 indexB,則提取字符一直到字符串末尾;
          • 若 任一參數小于 0 或 NaN,則被當作 0;
          • 若 任一參數大于 length,則被當作 length。
          • 而 如果 indexA > indexB,則 substring 的執行效果就像是兩個參數調換一般。比如:str.substring(0, 1)==str.substring(1, 0)
          var str="Get outside every day. Miracles are waiting everywhere.";
          console.log(str.substring(1,1)); // ""
          console.log(str.substring(0)); // Get outside every day. Miracles are waiting everywhere.
          console.log(str.substring(-1)); // Get outside every day. Miracles are waiting everywhere.
          console.log(str.substring(0,100)); // Get outside every day. Miracles are waiting everywhere.
          console.log(str.substring(22,NaN)); // Get outside every day.
          

          toLocaleLowerCase & toLocaleUpperCase

          toLocaleLowerCase() 方法返回調用該方法的字符串被轉換成小寫的值,轉換規則根據本地化的大小寫映射。而toLocaleUpperCase() 方法則是轉換成大寫的值。

          語法:str.toLocaleLowerCase(), str.toLocaleUpperCase()

          console.log('ABCDEFG'.toLocaleLowerCase()); // abcdefg
          console.log('abcdefg'.toLocaleUpperCase()); // ABCDEFG
          

          toLowerCase & toUpperCase

          這兩個方法分別表示將字符串轉換為相應的小寫,大寫形式,并返回

          console.log('ABCDEFG'.toLowerCase()); // abcdefg
          console.log('abcdefg'.toUpperCase()); // ABCDEFG
          

          toString & valueOf

          這兩個方法都是返回字符串本身。

          語法:str.toString(), str.valueOf()

          var str="abc";
          console.log(str.toString()); // abc
          console.log(str.toString()==str.valueOf()); // true
          

          對于對象而言,toString和valueOf也是非常的相似,它們之間有著細微的差別,請嘗試運行以下一段代碼:

          var x={
           toString: function () { return "test"; },
           valueOf: function () { return 123; }
          };
          console.log(x); // test
          console.log("x=" + x); // "x=123"
          console.log(x + "=x"); // "123=x"
          console.log(x + "1"); // 1231
          console.log(x + 1); // 124
          console.log(["x=", x].join("")); // "x=test"
          

          當 “+” 操作符一邊為數字時,對象x趨向于轉換為數字,表達式會優先調用 valueOf 方法,如果調用數組的 join 方法,對象x趨向于轉換為字符串,表達式會優先調用 toString 方法。

          trim

          trim() 方法清除字符串首尾的空白并返回。

          語法:str.trim()

          console.log(" a b c ".trim()); // "a b c"
          

          trim() 方法是 ECMAScript 5.1 標準加入的,它并不支持IE9以下的低版本IE瀏覽器

          if(!String.prototype.trim) {
           String.prototype.trim=function () {
           return this.replace(/^\s+|\s+$/g,'');
           };
          }
          

          codePointAt(ES6)

          codePointAt() 方法基于ECMAScript 2015(ES6)規范,返回使用UTF-16編碼的給定位置的值的非負整數。

          語法:str.codePointAt(position)

          console.log("a".codePointAt(0)); // 97
          console.log("\u4f60\u597d".codePointAt(0)); // 20320
          

          includes(ES6)

          includes() 方法基于ECMAScript 2015(ES6)規范,它用來判斷一個字符串是否屬于另一個字符。如果是,則返回true,否則返回false。

          語法:str.includes(subString [, position])

          subString 表示要搜索的字符串,position 表示從當前字符串的哪個位置開始搜索字符串,默認值為0。

          var str="Practice makes perfect.";
          console.log(str.includes("perfect")); // true
          console.log(str.includes("perfect",100)); // false
          

          實際上,Firefox 18~39中該方法的名稱為contains,由于bug 1102219的存在,它被重命名為includes() 。目前只有Chrome v41+和Firefox v40+版本瀏覽器實現了它,如需在其它版本瀏覽器中使用該方法,請參考 Polyfill。

          endsWith(ES6)

          endsWith() 方法基于ECMAScript 2015(ES6)規范,它基本與 contains() 功能相同,不同的是,它用來判斷一個字符串是否是原字符串的結尾。若是則返回true,否則返回false。

          語法:str.endsWith(substring [, position])

          與contains 方法不同,position 參數的默認值為字符串長度。

          var str="Learn and live.";
          console.log(str.endsWith("live.")); // true
          console.log(str.endsWith("Learn",5)); // true
          

          startsWith(ES6)

          startsWith() 方法基于ECMAScript 2015(ES6)規范,它用來判斷當前字符串是否是以給定字符串開始的,若是則返回true,否則返回false。

          語法:str.startsWith(subString [, position])

          var str="Where there is a will, there is a way.";
          console.log(str.startsWith("Where")); // true
          console.log(str.startsWith("there",6)); // true
          

          normalize(ES6)

          normalize() 方法基于ECMAScript 2015(ES6)規范,它會按照指定的 Unicode 正規形式將原字符串正規化。

          語法:str.normalize([form])

          form 參數可省略,目前有四種 Unicode 正規形式,即 “NFC”、”NFD”、”NFKC” 以及 “NFKD”,form的默認值為 “NFC”。如果form 傳入了非法的參數值,則會拋出 RangeError 錯誤。

          var str="\u4f60\u597d";
          console.log(str.normalize()); // 你好
          console.log(str.normalize("NFC")); // 你好
          console.log(str.normalize("NFD")); // 你好
          console.log(str.normalize("NFKC")); // 你好
          console.log(str.normalize("NFKD")); // 你好
          function toUnicode(theString) {
           var unicodeString='';
           for (var i=0; i < theString.length; i++) {
           var theUnicode=theString.charCodeAt(i).toString(16).toUpperCase();
           while (theUnicode.length < 4) {
           theUnicode='0' + theUnicode;
           }
           theUnicode='\\u' + theUnicode;
           unicodeString +=theUnicode;
           }
           return unicodeString;
          }
          toUnicode('你好'); // "\u4f60\u597d"
          

          repeat(ES6)

          repeat() 方法基于ECMAScript 2015(ES6)規范,它返回重復原字符串多次的新字符串。

          語法:str.repeat(count)

          count 參數只能取大于等于0 的數字。若該數字不為整數,將自動轉換為整數形式,若為負數或者其他值將報錯。

          var str="A still tongue makes a wise head.";
          console.log(str.repeat(0)); // ""
          console.log(str.repeat(1)); // A still tongue makes a wise head.
          console.log(str.repeat(1.5)); // A still tongue makes a wise head.
          console.log(str.repeat(-1)); // RangeError:Invalid count value
          

          HTML有關的方法

          常用的方法有 anchor,link 其它方法如 big、blink、bold、fixed、fontcolor、fontsize、italics、small、strike、sub、sup均已廢除。

          接下來我們將介紹 anchor 和 link 兩個方法,其他廢除方法不作介紹。

          anchor

          anchor() 方法創建一個錨標簽。

          語法:str.anchor(name)

          name 指定被創建的a標簽的name屬性,使用該方法創建的錨點,將會成為 document.anchors 數組的元素。

          var str="this is a anchor tag";
          document.body.innerHTML=document.body.innerHTML + str.anchor("anchor1"); // body末尾將會追加這些內容 <a name="anchor1">this is a anchor tag</a>
          

          link

          link() 方法同樣創建一個a標簽。

          語法:str.link(url)

          url 指定被創建的a標簽的href屬性,如果url中包含特殊字符,將自動進行編碼。例如 " 會被轉義為 &\quot。 使用該方法創建的a標簽,將會成為 document.links 數組中的元素。

          var str="百度";
          document.write(str.link("https://www.baidu.com")); // <a >百度</a>
          

          小結

          部分字符串方法之間存在很大的相似性,要注意區分他們的功能和使用場景。如:

          substr 和 substring,都是兩個參數,作用基本相同,兩者第一個參數含義相同,但用法不同,前者可為負數,后者值為負數或者非整數時將隱式轉換為0。前者第二個參數表示截取字符串的長度,后者第二個參數表示截取字符串的下標;同時substring第一個參數大于第二個參數時,執行結果同位置調換后的結果。 search方法與indexOf方法作用基本一致,都是查詢到了就返回子串第一次出現的下標,否則返回-1,唯一的區別就在于search默認會將子串轉化為正則表達式形式,而indexOf不做此處理,也不能處理正則。 另外,還記得嗎?concat方法由于效率問題,不推薦使用。

          通常,字符串中,常用的方法就charAt、indexOf、lastIndexOf、match、replace、search、slice、split、substr、substring、toLowerCase、toUpperCase、trim、valueof 等這些。熟悉它們的語法規則就能熟練地駕馭字符串

          參考文章:

          https://segmentfault.com/a/1190000010753942

          https://segmentfault.com/a/1190000012688190

          https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String

          ypeScript 和 JavaScript 是目前項目開發中較為流行的兩種腳本語言,我們已經熟知 TypeScript 是 JavaScript 的一個超集,但是 TypeScript 與 JavaScript 之間又有什么樣的區別呢?在選擇開發語言時,又該如何抉擇呢?

          本文將會深入對比這兩種語言,討論兩種語言之間的關聯和差異,并概述兩種語言各自的優勢。

          JavaScript 和 TypeScript 的概要介紹

          JavaScript

          JavaScript 是一種輕量級的解釋性腳本語言,可嵌入到 HTML 頁面中,在瀏覽器端執行,能夠實現瀏覽器端豐富的交互功能,為用戶帶來流暢多樣的用戶體驗。

          JavaScript 是基于對象和事件驅動的,無需特定的語言環境,只需在支持的瀏覽器上就能運行。

          JavaScript 語言具有以下特點:

          JavaScript 是一種腳本編寫語言,無需編譯,只要嵌入 HTML 代碼中,就能由瀏覽器逐行加載解釋執行。

          JavaScript 是一種基于對象的語言,可以創建對象同時使用現有對象。但是 Javascript 并不支持其它面向對象語言所具有的繼承和重載功能。

          JavaScript 的語法簡單,使用的變量為弱類型。

          JavaScript 語言較為安全,僅在瀏覽器端執行,不會訪問本地硬盤數據。

          JavaScript 語言具有動態性。JavaScript 是事件驅動的,只根據用戶的操作做出相應的反應處理。

          JavaScript 只依賴于瀏覽器,與操作系統的因素無關。因此 JavaScript 是一種跨平臺的語言。

          JavaScript 兼容性較好,能夠與其他技術(如 XML,REST API 等)一起使用。

          TypeScript

          TypeScript 是 Microsoft 開發和維護的一種面向對象的編程語言。它是 JavaScript 的超集,包含了 JavaScript 的所有元素,可以載入 JavaScript 代碼運行,并擴展了 JavaScript 的語法。

          TypeScript 具有以下特點:

          TypeScript 是 Microsoft 推出的開源語言,使用 Apache 授權協議

          TypeScript 增加了靜態類型、類、模塊、接口和類型注解

          TypeScript 可用于開發大型的應用

          TypeScript 易學易于理解

          JavaScript 和 TypeScript 的主要差異

          TypeScript 可以使用 JavaScript 中的所有代碼和編碼概念,TypeScript 是為了使 JavaScript 的開發變得更加容易而創建的。例如,TypeScript 使用類型和接口等概念來描述正在使用的數據,這使開發人員能夠快速檢測錯誤并調試應用程序

          TypeScript 從核心語言方面和類概念的模塑方面對 JavaScript 對象模型進行擴展。

          JavaScript 代碼可以在無需任何修改的情況下與 TypeScript 一同工作,同時可以使用編譯器將 TypeScript 代碼轉換為 JavaScript。

          TypeScript 通過類型注解提供編譯時的靜態類型檢查。

          TypeScript 中的數據要求帶有明確的類型,JavaScript不要求。

          TypeScript 為函數提供了缺省參數值。

          TypeScript 引入了 JavaScript 中沒有的“類”概念。

          TypeScript 中引入了模塊的概念,可以把聲明、數據、函數和類封裝在模塊中。

          TypeScript 的優勢

          下面列舉 TypeScript 相比于 JavaScript 的顯著優勢:

          1. 靜態輸入

          靜態類型化是一種功能,可以在開發人員編寫腳本時檢測錯誤。查找并修復錯誤是當今開發團隊的迫切需求。有了這項功能,就會允許開發人員編寫更健壯的代碼并對其進行維護,以便使得代碼質量更好、更清晰。

          2. 大型的開發項目

          有時為了改進開發項目,需要對代碼庫進行小的增量更改。這些小小的變化可能會產生嚴重的、意想不到的后果,因此有必要撤銷這些變化。使用TypeScript工具來進行重構更變的容易、快捷。

          3. 更好的協作

          當發開大型項目時,會有許多開發人員,此時亂碼和錯誤的機也會增加。類型安全是一種在編碼期間檢測錯誤的功能,而不是在編譯項目時檢測錯誤。這為開發團隊創建了一個更高效的編碼和調試過程。

          4. 更強的生產力

          干凈的 ECMAScript 6 代碼,自動完成和動態輸入等因素有助于提高開發人員的工作效率。這些功能也有助于編譯器創建優化的代碼。

          JavaScript 的優勢

          相比于 TypeScript,JavaScript 也有一些明顯優勢。

          1. 人氣

          JavaScript 的開發者社區仍然是巨大而活躍的,在社區中可以很方便地找到大量成熟的開發項目和可用資源。

          2. 學習曲線

          由于 JavaScript 語言發展的較早,也較為成熟,所以仍有一大批開發人員堅持使用他們熟悉的腳本語言 JavaScript,而不是學習 TypeScript。

          3. 本地瀏覽器支持

          TypeScript 代碼需要被編譯(輸出 JavaScript 代碼),這是 TypeScript 代碼執行時的一個額外的步驟。

          4. 不需要注釋

          為了充分利用 TypeScript 特性,開發人員需要不斷注釋他們的代碼,這可能會使項目效率降低。

          5. 靈活性

          有些開發人員更喜歡 JavaScript 的靈活性。

          如何抉擇

          TypeScript 正在成為開發大型編碼項目的有力工具。因為其面向對象編程語言的結構保持了代碼的清潔、一致和簡單的調試。因此在應對大型開發項目時,使用 TypeScript 更加合適。如果有一個相對較小的編碼項目,似乎沒有必要使用 TypeScript,只需使用靈活的 JavaScript 即可。


          主站蜘蛛池模板: 中文字幕一区二区三区视频在线| 久久精品国产第一区二区三区| 精品综合一区二区三区| 国产成人精品一区二区三区| 日本精品无码一区二区三区久久久| 狠狠爱无码一区二区三区| 日本一区二区三区在线网| 久久综合九九亚洲一区| 欧美人妻一区黄a片| 日韩高清国产一区在线| 成人精品一区二区不卡视频| 成人区精品人妻一区二区不卡| 免费一区二区无码东京热| 国产精品毛片一区二区| 国产成人无码一区二区在线播放 | 国产成人高清精品一区二区三区| 人妻无码一区二区三区四区| 国产一区二区三区久久精品| 精品无码国产一区二区三区AV| 熟女少妇丰满一区二区| 国产av成人一区二区三区| 香蕉视频一区二区| 国产一区二区在线看| 亚洲一区二区三区在线网站| 国产suv精品一区二区6| 精品永久久福利一区二区| 精品无码一区二区三区爱欲九九 | 精品爆乳一区二区三区无码av| 国产精品日韩欧美一区二区三区 | 国产区精品一区二区不卡中文| 538国产精品一区二区在线| 成人H动漫精品一区二区| 无码中文人妻在线一区 | 国产精品va一区二区三区| 亚洲国产综合精品一区在线播放| 一区二区三区视频在线| 无码日韩精品一区二区人妻 | 无码少妇一区二区浪潮免费| 三上悠亚日韩精品一区在线| 国产精品无码一区二区三区免费 | 亚洲中文字幕在线无码一区二区|