亚洲国产精品无码久久大片,亚洲AV无码乱码麻豆精品国产,亚洲品质自拍网站,少妇伦子伦精品无码STYLES,国产精久久久久久久

文章采集調用

文章采集調用

文章采集調用 Java 中拼接 String 的 N 種方式

采集交流 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 168 次瀏覽 ? 2022-05-01 09:32 ? 來(lái)自相關(guān)話(huà)題

  文章采集調用 Java 中拼接 String 的 N 種方式
  
  1. 前言
  Java 提供了拼接 String 字符串的多種方式,不過(guò)有時(shí)候如果我們不注意 null 字符串的話(huà),可能會(huì )把 null 拼接到結果當中,很明顯這不是我們想要的。
  在這篇文章中,將介紹一些在拼接 String 時(shí)避免 null 值的幾種方式。
  2. 問(wèn)題復現
  如果我們想要拼接 String 數組,可以簡(jiǎn)單的使用 + 運算符進(jìn)行拼接,但是可能會(huì )遇到 null 值。
  String[]?values?=?{"https",?"://",?"www.",?"wdbyte",?".com",?null};<br />String?result?=?"";<br /><br />for?(String?value?:?values)?{<br />????result?=?result?+?value;<br />}<br />
  這會(huì )將所有元素拼接到結果字符串中,如下所示:
  https://www.wdbyte.comnull<br />
  但是,我們已經(jīng)發(fā)現問(wèn)題了,最后的 null 值作為字符串也拼接了下來(lái),這顯然不是我們想要的。
  同樣,即使我們在 Java 8 或更高版本上運行,然后使用String.join() 靜態(tài)方法拼接字符串,一樣會(huì )得到帶有 null 值的輸出。
  String[]?values?=?{"https",?"://",?"www.",?"wdbyte",?".com",?null};<br />String?result?=?String.join("",?values);<br />//?output:?https://www.wdbyte.comnull<br />
  下面看看一些可以避免 null 值被拼接下來(lái)的方法,我的期待的輸出結果應該是:
  https://www.wdbyte.com<br />
  3. 使用 + 運算符
  加法符號 + 可以拼接 String 字符串,那么我們只需要在拼接時(shí)進(jìn)行 null 判斷就可以把 null 值替換為空字符串了。
  for?(String?value?:?values)?{<br />??result?=?result?+?(value?==?null???""?:?value);<br />}<br />
  然而,我們知道 String 是一個(gè)不可變對象,使用 + 號會(huì )頻繁的創(chuàng )建字符串對象,每次都會(huì )在內存中創(chuàng )建一個(gè)新的字符串,所以使用 + 符號來(lái)拼接字符串的性能消耗是很高的。
  為了方便后續的代碼演示,我們抽取一個(gè)可以傳入字符串,返回一個(gè)非 null 字符串的方法。
  public?String?nullToString(String?value)?{<br />????return?value?==?null???""?:?value;<br />}<br />
  因此上面的代碼可以改為調用這個(gè)方法:
  for?(String?value?:?values)?{<br />????result?=?result?+?nullToString(value);<br />}<br />
  4. 使用 String.concat()
  String.concat() 是 String 類(lèi)自帶的一個(gè)方法,使用這種方式拼接字符串十分方便。
  for?(String?value?:?values)?{<br />????result?=?result.concat(getNonNullString(value));<br />}<br />
  因為調用了 nullToString() 方法,因此得到的結果中沒(méi)有 null 值。
  5. 使用 StringBuilder
  StringBuilder 類(lèi)提供了很多有用且方便的 String 構建方法。其中比較常用的是 append() 方法,使用 append() 來(lái)拼接字符串,同時(shí)結合 nullToString() 方法來(lái)避免 null 值。
  String[]?values?=?{"https",?"://",?"www.",?"wdbyte",?".com",?null};<br />StringBuilder?result?=?new?StringBuilder();<br />for?(String?value?:?values)?{<br />????result?=?result.append(nullToString(value));<br />}<br />
  可以得到如下結果:
  https://www.wdbyte.com<br />
  6. 使用 StringJoiner 類(lèi) (Java 8+)
  StringJoiner 類(lèi)提供了更強大的字符串拼接功能,不僅可以指定拼接時(shí)的分隔符,還可以指定拼接時(shí)的前綴和后綴,這里我們可以使用它的 add()方法來(lái)拼接字符串。
  同樣的會(huì )用 nullToString() 方法來(lái)避免 null 值。
  String[]?values?=?{"https",?"://",?"www.",?"wdbyte",?".com",?null};<br />StringJoiner?result?=?new?StringJoiner("");<br />for?(String?value?:?values)?{<br />????result?=?result.add(nullToString(value));<br />}<br />
  7. 使用 Streams.filter (Java 8+)
  Stream API 是 Java 8 引入的功能強大的流式操作類(lèi),可以進(jìn)行常見(jiàn)的過(guò)濾、映射、遍歷、分組、統計等操作。其中的過(guò)濾操作 filter 可以接收一個(gè) Predicate 函數,Predicate 函數接口同之前介紹的 Function (opens new window)接口一樣,是一個(gè)函數式接口,它可以接受一個(gè)泛型 參數,返回值為布爾類(lèi)型,Predicate 常用于數據過(guò)濾。
  因此,我們可以定義一個(gè)Predicate 來(lái)檢查為 null 的字符串,然后傳遞給 Stream API 的 filter() 方法。
  最后再使用 Collectors.joining() 方法拼接剩余的非 null 字符串。
  String[]?values?=?{"https",?"://",?"www.",?"wdbyte",?".com",?null};<br />String?result?=?Arrays.stream(values)<br />????.filter(Objects::nonNull)<br />????.collect(Collectors.joining());<br />
  8. 總結
  這篇文章介紹了拼接非 null 字符串的幾種方式,不同的方式可能適合不同的場(chǎng)景,不過(guò)要注意拼接String 字符串是一項昂貴的操作,下面是使用 JMH 對幾種拼接方式進(jìn)行基準測試的結果。
  Benchmark???????????????????Mode???Cnt???????Score????????Error??Units<br />StringConcat.operateAdd?????thrpt???25??13635005.992?±?549759.774??ops/s<br />StringConcat.String.concat??thrpt???25???7465193.417?±?667928.552??ops/s<br />StringConcat.StringBuilder??thrpt???25??13949781.608?±?142001.421??ops/s<br />StringConcat.StringJoiner???thrpt???25???9502405.473?±?211977.433??ops/s<br />StringConcat.StreamFilter???thrpt???25???8998396.107?±?649033.722??ops/s<br />
  可以看到 StringBuilder 的性能是最好的,實(shí)際使用時(shí)要結合具體場(chǎng)景,然后選擇最低的性能開(kāi)銷(xiāo)方式。
  <p data-darkmode-bgcolor="rgb(36, 36, 36)" data-darkmode-original-bgcolor="rgb(255, 255, 255)" data-darkmode-color="rgb(106, 104, 111)" data-darkmode-original-color="rgb(106, 104, 111)" data-darkmode-bgcolor-15923650965579="rgb(36, 36, 36)" data-darkmode-original-bgcolor-15923650965579="rgb(255, 255, 255)" data-darkmode-color-15923650965579="rgb(106, 104, 111)" data-darkmode-original-color-15923650965579="rgb(106, 104, 111)" style="margin-right: 0em;margin-left: 0em;outline: 0px;color: rgb(106, 104, 111);">1.?SQL優(yōu)化萬(wàn)能公式:5 大步驟 + 10 個(gè)案例
  2.?大型 SaaS 平臺產(chǎn)品架構設計
  3.?Spring Cloud 分布式日志采集方案,建議收藏!
  4.?POI 導出 Excel:字體顏色、行列自適應、鎖住、合并單元格、一文搞定……
  
  最近面試BAT,整理一份面試資料《Java面試BATJ通關(guān)手冊》,覆蓋了Java核心技術(shù)、JVM、Java并發(fā)、SSM、微服務(wù)、數據庫、數據結構等等。
  獲取方式:點(diǎn)“在看”,關(guān)注公眾號并回復?Java?領(lǐng)取,更多內容陸續奉上。</p>
  <p data-tool="mdnice編輯器" style="margin-top: 10px;margin-bottom: 10px;padding-top: 8px;padding-bottom: 8px;outline: 0px;white-space: normal;font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-align: right;line-height: 1.6;color: rgb(63, 63, 63);">PS:因公眾號平臺更改了推送規則,如果不想錯過(guò)內容,記得讀完點(diǎn)一下“在看”,加個(gè)“星標”,這樣每次新文章推送才會(huì )第一時(shí)間出現在你的訂閱列表里。
  點(diǎn)“在看”支持小哈呀,謝謝啦<strong style="outline: 0px;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;color: rgb(0, 128, 255);font-size: 15px;"></strong></p> 查看全部

  文章采集調用 Java 中拼接 String 的 N 種方式
  
  1. 前言
  Java 提供了拼接 String 字符串的多種方式,不過(guò)有時(shí)候如果我們不注意 null 字符串的話(huà),可能會(huì )把 null 拼接到結果當中,很明顯這不是我們想要的。
  在這篇文章中,將介紹一些在拼接 String 時(shí)避免 null 值的幾種方式。
  2. 問(wèn)題復現
  如果我們想要拼接 String 數組,可以簡(jiǎn)單的使用 + 運算符進(jìn)行拼接,但是可能會(huì )遇到 null 值。
  String[]?values?=?{"https",?"://",?"www.",?"wdbyte",?".com",?null};<br />String?result?=?"";<br /><br />for?(String?value?:?values)?{<br />????result?=?result?+?value;<br />}<br />
  這會(huì )將所有元素拼接到結果字符串中,如下所示:
  https://www.wdbyte.comnull<br />
  但是,我們已經(jīng)發(fā)現問(wèn)題了,最后的 null 值作為字符串也拼接了下來(lái),這顯然不是我們想要的。
  同樣,即使我們在 Java 8 或更高版本上運行,然后使用String.join() 靜態(tài)方法拼接字符串,一樣會(huì )得到帶有 null 值的輸出。
  String[]?values?=?{"https",?"://",?"www.",?"wdbyte",?".com",?null};<br />String?result?=?String.join("",?values);<br />//?output:?https://www.wdbyte.comnull<br />
  下面看看一些可以避免 null 值被拼接下來(lái)的方法,我的期待的輸出結果應該是:
  https://www.wdbyte.com<br />
  3. 使用 + 運算符
  加法符號 + 可以拼接 String 字符串,那么我們只需要在拼接時(shí)進(jìn)行 null 判斷就可以把 null 值替換為空字符串了。
  for?(String?value?:?values)?{<br />??result?=?result?+?(value?==?null???""?:?value);<br />}<br />
  然而,我們知道 String 是一個(gè)不可變對象,使用 + 號會(huì )頻繁的創(chuàng )建字符串對象,每次都會(huì )在內存中創(chuàng )建一個(gè)新的字符串,所以使用 + 符號來(lái)拼接字符串的性能消耗是很高的。
  為了方便后續的代碼演示,我們抽取一個(gè)可以傳入字符串,返回一個(gè)非 null 字符串的方法。
  public?String?nullToString(String?value)?{<br />????return?value?==?null???""?:?value;<br />}<br />
  因此上面的代碼可以改為調用這個(gè)方法:
  for?(String?value?:?values)?{<br />????result?=?result?+?nullToString(value);<br />}<br />
  4. 使用 String.concat()
  String.concat() 是 String 類(lèi)自帶的一個(gè)方法,使用這種方式拼接字符串十分方便。
  for?(String?value?:?values)?{<br />????result?=?result.concat(getNonNullString(value));<br />}<br />
  因為調用了 nullToString() 方法,因此得到的結果中沒(méi)有 null 值。
  5. 使用 StringBuilder
  StringBuilder 類(lèi)提供了很多有用且方便的 String 構建方法。其中比較常用的是 append() 方法,使用 append() 來(lái)拼接字符串,同時(shí)結合 nullToString() 方法來(lái)避免 null 值。
  String[]?values?=?{"https",?"://",?"www.",?"wdbyte",?".com",?null};<br />StringBuilder?result?=?new?StringBuilder();<br />for?(String?value?:?values)?{<br />????result?=?result.append(nullToString(value));<br />}<br />
  可以得到如下結果:
  https://www.wdbyte.com<br />
  6. 使用 StringJoiner 類(lèi) (Java 8+)
  StringJoiner 類(lèi)提供了更強大的字符串拼接功能,不僅可以指定拼接時(shí)的分隔符,還可以指定拼接時(shí)的前綴和后綴,這里我們可以使用它的 add()方法來(lái)拼接字符串。
  同樣的會(huì )用 nullToString() 方法來(lái)避免 null 值。
  String[]?values?=?{"https",?"://",?"www.",?"wdbyte",?".com",?null};<br />StringJoiner?result?=?new?StringJoiner("");<br />for?(String?value?:?values)?{<br />????result?=?result.add(nullToString(value));<br />}<br />
  7. 使用 Streams.filter (Java 8+)
  Stream API 是 Java 8 引入的功能強大的流式操作類(lèi),可以進(jìn)行常見(jiàn)的過(guò)濾、映射、遍歷、分組、統計等操作。其中的過(guò)濾操作 filter 可以接收一個(gè) Predicate 函數,Predicate 函數接口同之前介紹的 Function (opens new window)接口一樣,是一個(gè)函數式接口,它可以接受一個(gè)泛型 參數,返回值為布爾類(lèi)型,Predicate 常用于數據過(guò)濾。
  因此,我們可以定義一個(gè)Predicate 來(lái)檢查為 null 的字符串,然后傳遞給 Stream API 的 filter() 方法。
  最后再使用 Collectors.joining() 方法拼接剩余的非 null 字符串。
  String[]?values?=?{"https",?"://",?"www.",?"wdbyte",?".com",?null};<br />String?result?=?Arrays.stream(values)<br />????.filter(Objects::nonNull)<br />????.collect(Collectors.joining());<br />
  8. 總結
  這篇文章介紹了拼接非 null 字符串的幾種方式,不同的方式可能適合不同的場(chǎng)景,不過(guò)要注意拼接String 字符串是一項昂貴的操作,下面是使用 JMH 對幾種拼接方式進(jìn)行基準測試的結果。
  Benchmark???????????????????Mode???Cnt???????Score????????Error??Units<br />StringConcat.operateAdd?????thrpt???25??13635005.992?±?549759.774??ops/s<br />StringConcat.String.concat??thrpt???25???7465193.417?±?667928.552??ops/s<br />StringConcat.StringBuilder??thrpt???25??13949781.608?±?142001.421??ops/s<br />StringConcat.StringJoiner???thrpt???25???9502405.473?±?211977.433??ops/s<br />StringConcat.StreamFilter???thrpt???25???8998396.107?±?649033.722??ops/s<br />
  可以看到 StringBuilder 的性能是最好的,實(shí)際使用時(shí)要結合具體場(chǎng)景,然后選擇最低的性能開(kāi)銷(xiāo)方式。
  <p data-darkmode-bgcolor="rgb(36, 36, 36)" data-darkmode-original-bgcolor="rgb(255, 255, 255)" data-darkmode-color="rgb(106, 104, 111)" data-darkmode-original-color="rgb(106, 104, 111)" data-darkmode-bgcolor-15923650965579="rgb(36, 36, 36)" data-darkmode-original-bgcolor-15923650965579="rgb(255, 255, 255)" data-darkmode-color-15923650965579="rgb(106, 104, 111)" data-darkmode-original-color-15923650965579="rgb(106, 104, 111)" style="margin-right: 0em;margin-left: 0em;outline: 0px;color: rgb(106, 104, 111);">1.?SQL優(yōu)化萬(wàn)能公式:5 大步驟 + 10 個(gè)案例
  2.?大型 SaaS 平臺產(chǎn)品架構設計
  3.?Spring Cloud 分布式日志采集方案,建議收藏!
  4.?POI 導出 Excel:字體顏色、行列自適應、鎖住、合并單元格、一文搞定……
  
  最近面試BAT,整理一份面試資料《Java面試BATJ通關(guān)手冊》,覆蓋了Java核心技術(shù)、JVM、Java并發(fā)、SSM、微服務(wù)、數據庫、數據結構等等。
  獲取方式:點(diǎn)“在看”,關(guān)注公眾號并回復?Java?領(lǐng)取,更多內容陸續奉上。</p>
  <p data-tool="mdnice編輯器" style="margin-top: 10px;margin-bottom: 10px;padding-top: 8px;padding-bottom: 8px;outline: 0px;white-space: normal;font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-align: right;line-height: 1.6;color: rgb(63, 63, 63);">PS:因公眾號平臺更改了推送規則,如果不想錯過(guò)內容,記得讀完點(diǎn)一下“在看”,加個(gè)“星標”,這樣每次新文章推送才會(huì )第一時(shí)間出現在你的訂閱列表里。
  點(diǎn)“在看”支持小哈呀,謝謝啦<strong style="outline: 0px;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;color: rgb(0, 128, 255);font-size: 15px;"></strong></p>

數據治理 | 數據分析與清洗工具:Pandas 數據類(lèi)型轉換(贈送本文同款數據!

采集交流 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 116 次瀏覽 ? 2022-05-01 09:11 ? 來(lái)自相關(guān)話(huà)題

  數據治理 | 數據分析與清洗工具:Pandas 數據類(lèi)型轉換(贈送本文同款數據!
  Part1前言上期文章中,我們介紹了數據中的各種類(lèi)型的缺失值以及如何處理這些缺失值;同時(shí)也介紹了常見(jiàn)的數據重復問(wèn)題并奉上了處理重復數據的方法。這些處理方法對大家的數據治理、數據分析工作都有著(zhù)至關(guān)重要的作用。本期文章將會(huì )繼續學(xué)習 Pandas 工具,學(xué)習如何轉換數據類(lèi)型。讀完本文后,靈活轉換數據類(lèi)型將不再是問(wèn)題!本文中所有 Python 代碼均在集成開(kāi)發(fā)環(huán)境 Visual Studio Code (VScode) 中使用交互式開(kāi)發(fā)環(huán)境 Jupyter Notebook 編寫(xiě)。Part2為什么需要做數據類(lèi)型轉換數據的含義與數據的類(lèi)型是息息相關(guān)的,正確的數據類(lèi)型能夠支撐數據含義的正確表示。當一些數據的類(lèi)型出現錯亂時(shí),它們的含義也會(huì )變得“詭異”。請看下面幾個(gè)例子:
  錯誤示范
  正確示范
  原因解析
  今年是 2022.0年
  今年是 2022 年
  2022 作為一個(gè)年份時(shí),應該保存為整數型或者字符型,而不是浮點(diǎn)型(小數型)數字 2022.0
  圓周率保留兩位小數的結果是3
  圓周率保留兩位小數的結果是 3.14
  圓周率保留兩位小數應該是浮點(diǎn)數 3.14,如果轉為整數型,其結果就會(huì )是 3
  1 + 1 = 11
  1 + 1 = 2
  1 + 1 = 11 實(shí)際上是字符串拼接,即 '1' + '1' 得到了 '11'
  [0, 1, 2] 的第一個(gè)元素是[
  [0, 1, 2] 的第一個(gè)元素是 0
  列表 [0, 1, 2] 被保存為字符型,它的真面目是 "[0, 1, 2]",這個(gè)字符串的第一個(gè)元素是 '[' 而不是 0
  我們早已經(jīng)知道,Python 中字符串是用英文引號引起來(lái)的,就像是 'Python',"Python"。你可能會(huì )覺(jué)得,既然如此,數字型數據和字符型數據不就不容易搞混了嗎?例如,數字 2022 和 字符串 "2022" ,很容易就能區分。然而,實(shí)際的情況卻是,容易搞混,很容易搞混!這是因為在 Pandas 中,所有字符數據前后的引號都不會(huì )顯示出來(lái),如果顯示出了引號,那么這些引號也是字符串中的字符。所以使用 Pandas 處理數據,為了避免類(lèi)似的情況出現,學(xué)習數據類(lèi)型轉換是非常有必要的。Part3類(lèi)型轉換大多數時(shí)候,數據中不同字段的數據類(lèi)型是不一定全都一樣;同一個(gè)字段中,數據的類(lèi)型是一般是一致的。所以進(jìn)行數據類(lèi)型轉換時(shí)不需要一個(gè)一個(gè)對數據值做類(lèi)型轉換,直接操作一個(gè)字段會(huì )更加方便。我們使用本期贈送的數據作為介紹 Pandas 的示例數據,使用 Excel 打開(kāi)數據【5G 產(chǎn)業(yè)全國各省市分年度專(zhuān)利申請、專(zhuān)利授權情況(2000-2019.9).xlsx】,如下圖所示:
  
  贈送的數據中沒(méi)有缺失值,其中值為數字的字段在 Excel 中是數字類(lèi)型;我們使用 Pandas 讀取 Excel 或者 csv 數據時(shí),系統會(huì )自動(dòng)地將每個(gè)字段讀取為合適的數據類(lèi)型。如果需要自定義一些(或者所有)字段的類(lèi)型,我們也可以自己指定每個(gè)字段的數據類(lèi)型(數據必須滿(mǎn)足指定類(lèi)型的格式,例如我們不可以將 “省份名” 字段設置為 整數型)。使用 Pandas 讀取這個(gè) Excel 數據,代碼和輸出如下:
  #?數據存儲的路徑<br />path?=?'./5G?產(chǎn)業(yè)全國各省市分年度專(zhuān)利申請、專(zhuān)利授權情況(2000-2019.9).xlsx'<br />#?這里指定字段的數據類(lèi)型<br />columns_type?=?{'年份':'str',?<br />????????????????'省份名':'str',?<br />????????????????'省份行政代碼':'int',?????????????????????????????????<br />????????????????'專(zhuān)利申請':'int',?<br />????????????????'專(zhuān)利授權':'int',?<br />????????????????'專(zhuān)利類(lèi)型':'str'}<br />#?dtype?參數用于指定字段的類(lèi)型,如果不需要特意指定字段的類(lèi)型,不使用?dtype?參數即可<br />data?=?pd.read_excel(path,?dtype=columns_type)<br />data<br />
  
  讀取數據后我們使用 Pandas 中的相關(guān)方法生成一個(gè)新的列,這一列中的數據是一個(gè)包含專(zhuān)利申請、專(zhuān)利授權和專(zhuān)利類(lèi)型的列表。操作代碼和新生成的數據如下:
  #?根據專(zhuān)利申請、專(zhuān)利授權和專(zhuān)利類(lèi)型三個(gè)字段得到一個(gè)新字段<br />data['列表']?=?data.apply(lambda?X:?[X['專(zhuān)利申請'],?X['專(zhuān)利授權'],?X['專(zhuān)利類(lèi)型']]?,axis=1)<br />data<br />
  
  將新生成的數據保存為 csv 文件后再讀取,讀取時(shí)我們故意將部分字段讀取為錯誤的類(lèi)型,隨后使用錯誤的數據來(lái)給大家演示如何進(jìn)行數據類(lèi)型的轉換。
  #?將剛剛新生成的數據保存為?csv?文件<br />#?參數 index=False 的含義是,不講數據索引寫(xiě)入 csv 文件中<br />data.to_csv('新數據.csv',?index=False)<br /><br />#?使用錯誤的字段類(lèi)型重新讀取數據<br />#?我們將年份讀取為浮點(diǎn)型(小數型),將專(zhuān)利申請讀取為字符型<br />wrong_type?=?{'年份':'float',???????????????????????????????????<br />??????????????'專(zhuān)利申請':'str'}<br />DATA?=?pd.read_csv('新數據.csv',?dtype=wrong_type)<br /><br />#?查看專(zhuān)利申請字段類(lèi)型<br />print(DATA.專(zhuān)利申請.dtype)??#?輸出:object,說(shuō)明該字段含有字符型數據<br />DATA<br />
  
  可以看到,“年份” 字段中所有的年份都變?yōu)樾敌?;通過(guò)代碼也判斷出 “專(zhuān)利申請” 字段不再是整數型,而是字符型,因為 DataFrame 中的字符型數據不會(huì )顯示兩端的引號,所以無(wú)法目測其類(lèi)型。那么這種內容為數字的字符型數據會(huì )給我們什么麻煩呢?假設我們需要使用 專(zhuān)利授權/ 專(zhuān)利申請 來(lái)計算專(zhuān)利授權率時(shí) ,會(huì )發(fā)現整數和字符之間無(wú)法運算。如果這兩個(gè)字段中的值的都是字符型,那么兩者只能進(jìn)行加法運算,例如:“45” + “8” == “458”,這恐怕更不是我們想要的結果。接下來(lái)我們使用數據類(lèi)型轉換的方法來(lái)糾正這些錯誤的數據。1使用 astype() 轉換基本類(lèi)型Pandas 專(zhuān)門(mén)為類(lèi)型轉換提供了一個(gè) astype() 方法,這個(gè)方法可以將數據類(lèi)型轉換為希望的類(lèi)型,既可以操作 Series,又可以操作 DataFrame,使用時(shí)只需要傳入轉換后的類(lèi)型即可。我們在往期的文章中提到過(guò),Pandas 中絕大多數涉及到數據修改的方法,他們都不會(huì )直接修改原始的數據,而是返回一個(gè)新的數據。astype()也是一樣的,默認返回一個(gè)新的數據。場(chǎng)景 1:將數據中的年份字段轉換為整數型
  #?將字段類(lèi)型由浮點(diǎn)型(小數型)轉換為整數型?int<br />#?返回一個(gè)新數據,調用該方法的是一個(gè)?Series,返回值也將是一個(gè)?Series<br />DATA['年份'].astype(int)<br />
  
  希望類(lèi)型轉換操作在原始數據中生效可以使用下面的代碼。
  #?將新生的數據重新賦值給原始數據即可<br />#?賦值操作不會(huì )返回任何值<br />DATA['年份']?=?DATA['年份'].astype(int)<br />#?輸出查看轉換后的數據<br />DATA<br />
  
  場(chǎng)景 2:將數據中所有內容轉換為字符型數據,轉換后的數據命名為ALL_STR
  #?將類(lèi)型轉換為字符型數據后的新數據命名為?ALL_STR<br />ALL_STR?=?DATA.astype(str)<br />#?查看新數據的信息<br />ALL_STR.info()<br />
  
  所有的字段類(lèi)型都變?yōu)?object,說(shuō)明所有字段中都含有字符型數據,操作生效。另外,當字段中存在無(wú)法轉換的數據值時(shí),可以指定參數 errors='ignore' 來(lái)忽略無(wú)法轉換的數據值。假如我們希望將所有字段都轉換為浮點(diǎn)型(小數型),但是字符型數據 “北京” 、“45”、“發(fā)明專(zhuān)利” 等字符型數據無(wú)法轉換為浮點(diǎn)型,我們則可以使用下面的代碼來(lái)轉換可以轉換的字段:
  #?指定參數?errors='ignore',忽略無(wú)法轉換的數據值<br />DATA.astype(float,?errors='ignore')<br />
  
  可以看到,除了一些字符型數據之外,其他的數字類(lèi)型數據都被轉換為浮點(diǎn)型(小數型)數據。同樣地,如果不進(jìn)行賦值操作,那么就會(huì )返回一個(gè)新的數據,而原始數據不會(huì )發(fā)生變化。2使用 eval() 轉換特殊類(lèi)型astype() 方法多用于浮點(diǎn)型 float、整數型 int 和 字符型 str 的轉換操作。當涉及到字符型轉化為列表,字典等 Python 的組合數據類(lèi)型時(shí),則需要使用 Python 自帶的方法 eval() 。該函數可以去掉字符串最外側的引號,并按照 Python 語(yǔ)句方式執行去掉引號后的字符內容。下面我們舉例介紹一下 eval() 的用法。
  #?對字符串?'12'?做轉換<br />eval('12')?????#?得到整數:12<br /><br />#?對字符串?'12.5'?做轉換<br />eval('12.5')???#?得到浮點(diǎn)數:12.5<br /><br />#?對字符串?'12+5'?做轉換<br />eval('12+5')???#?得到整數:17<br /><br />#?定義變量?a?后對字符串?'a'?做轉換<br />a?=?'20'<br />eval('a')??????#?得到 a 的值:20<br /><br />#?對字符串?"[11,12,'列表元素']"?做轉換<br />eval("[11,12,'列表元素']")?#?得到列表:[11, 12, '列表元素']<br /><br />#?定義變量?m,n?后對字符串?'[m,n,m-50]'?做轉換<br />m=100<br />n='某個(gè)字符串'<br />eval("[m,n,m-50]")??#?得到列表:[100, '某個(gè)字符串', 50]<br />
  根據上面的例子可以看出,eval() 確實(shí)可以去掉字符串最外側的引號,并按照 Python 語(yǔ)句方式執行去掉引號后的字符內容。這個(gè)方法不僅可以轉換列表形式的字符串,對諸如字典、元組以及集合等 Python 數據類(lèi)型形式的字符串,該方法依然可用。場(chǎng)景 3:將數據中“列表”字段轉換為 Python 列表類(lèi)型由于 eval() 方法操作的是字符串對象,一次只接受一個(gè)需要轉化的對象,當需要使用它來(lái)對 DataFrame 的一整個(gè)字段做轉換操作時(shí),需要借助循環(huán)或者其他的 Pandas 方法。
  #?輸出查看轉換之前"列表"字段最后一個(gè)值的類(lèi)型,原始的類(lèi)型為?str?型<br />print(type(DATA['列表'].values[-1]))<br />#?輸出:,確認是字符型<br /><br />#?方法 1:借助 for 循環(huán)<br />for?i?in?DATA.index:<br />????#?遍歷數據的索引<br />????#?根據索引找到待轉換的數據<br />????Target?=?DATA.loc[i,'列表']<br />????#?將轉換后的數據重新賦值給原來(lái)位置的數據值<br />????DATA['列表'][i]?=?eval(Target)<br />????<br />#?輸出查看"列表"字段最后一個(gè)值的類(lèi)型,若為列表,說(shuō)明轉換成功<br />print(type(DATA['列表'].values[-1]))<br />#?輸出:,轉換成功<br /><br />#?方法 2:借助 Pandas 方法 map()。不再輸出查看類(lèi)型<br />DATA['列表']?=?DATA['列表'].map(eval)<br /><br />#?方法 3:借助 Pandas 方法 apply()。不再輸出查看類(lèi)型<br />DATA['列表']?=?DATA['列表'].apply(eval)<br />
  后面兩種方法可以實(shí)現 方法 1 同樣的效果,且代碼量更少。Part4總結本期文章中,我們介紹了數據類(lèi)型錯誤帶來(lái)的影響,同時(shí)也介紹了轉換字段數據類(lèi)型的方法。使用類(lèi)型轉換方法可以在基本的數據類(lèi)型之間進(jìn)行合理的轉換。同時(shí)也介紹了轉換特殊數據類(lèi)型的方法。學(xué)習這些可以讓我們靈活地轉換數據的類(lèi)型,避免類(lèi)型錯亂帶來(lái)的麻煩。在最后的 場(chǎng)景3中,我們使用了map() 和 apply() 兩個(gè)方法,使用更少的代碼完成了同樣的功能。下期文章我們將會(huì )繼續介紹 Pandas,學(xué)習如何使用以上兩種方法來(lái)根據已有的數據生成新的數據列(數據列衍生)。
   查看全部

  數據治理 | 數據分析與清洗工具:Pandas 數據類(lèi)型轉換(贈送本文同款數據!
  Part1前言上期文章中,我們介紹了數據中的各種類(lèi)型的缺失值以及如何處理這些缺失值;同時(shí)也介紹了常見(jiàn)的數據重復問(wèn)題并奉上了處理重復數據的方法。這些處理方法對大家的數據治理、數據分析工作都有著(zhù)至關(guān)重要的作用。本期文章將會(huì )繼續學(xué)習 Pandas 工具,學(xué)習如何轉換數據類(lèi)型。讀完本文后,靈活轉換數據類(lèi)型將不再是問(wèn)題!本文中所有 Python 代碼均在集成開(kāi)發(fā)環(huán)境 Visual Studio Code (VScode) 中使用交互式開(kāi)發(fā)環(huán)境 Jupyter Notebook 編寫(xiě)。Part2為什么需要做數據類(lèi)型轉換數據的含義與數據的類(lèi)型是息息相關(guān)的,正確的數據類(lèi)型能夠支撐數據含義的正確表示。當一些數據的類(lèi)型出現錯亂時(shí),它們的含義也會(huì )變得“詭異”。請看下面幾個(gè)例子:
  錯誤示范
  正確示范
  原因解析
  今年是 2022.0年
  今年是 2022 年
  2022 作為一個(gè)年份時(shí),應該保存為整數型或者字符型,而不是浮點(diǎn)型(小數型)數字 2022.0
  圓周率保留兩位小數的結果是3
  圓周率保留兩位小數的結果是 3.14
  圓周率保留兩位小數應該是浮點(diǎn)數 3.14,如果轉為整數型,其結果就會(huì )是 3
  1 + 1 = 11
  1 + 1 = 2
  1 + 1 = 11 實(shí)際上是字符串拼接,即 '1' + '1' 得到了 '11'
  [0, 1, 2] 的第一個(gè)元素是[
  [0, 1, 2] 的第一個(gè)元素是 0
  列表 [0, 1, 2] 被保存為字符型,它的真面目是 "[0, 1, 2]",這個(gè)字符串的第一個(gè)元素是 '[' 而不是 0
  我們早已經(jīng)知道,Python 中字符串是用英文引號引起來(lái)的,就像是 'Python',"Python"。你可能會(huì )覺(jué)得,既然如此,數字型數據和字符型數據不就不容易搞混了嗎?例如,數字 2022 和 字符串 "2022" ,很容易就能區分。然而,實(shí)際的情況卻是,容易搞混,很容易搞混!這是因為在 Pandas 中,所有字符數據前后的引號都不會(huì )顯示出來(lái),如果顯示出了引號,那么這些引號也是字符串中的字符。所以使用 Pandas 處理數據,為了避免類(lèi)似的情況出現,學(xué)習數據類(lèi)型轉換是非常有必要的。Part3類(lèi)型轉換大多數時(shí)候,數據中不同字段的數據類(lèi)型是不一定全都一樣;同一個(gè)字段中,數據的類(lèi)型是一般是一致的。所以進(jìn)行數據類(lèi)型轉換時(shí)不需要一個(gè)一個(gè)對數據值做類(lèi)型轉換,直接操作一個(gè)字段會(huì )更加方便。我們使用本期贈送的數據作為介紹 Pandas 的示例數據,使用 Excel 打開(kāi)數據【5G 產(chǎn)業(yè)全國各省市分年度專(zhuān)利申請、專(zhuān)利授權情況(2000-2019.9).xlsx】,如下圖所示:
  
  贈送的數據中沒(méi)有缺失值,其中值為數字的字段在 Excel 中是數字類(lèi)型;我們使用 Pandas 讀取 Excel 或者 csv 數據時(shí),系統會(huì )自動(dòng)地將每個(gè)字段讀取為合適的數據類(lèi)型。如果需要自定義一些(或者所有)字段的類(lèi)型,我們也可以自己指定每個(gè)字段的數據類(lèi)型(數據必須滿(mǎn)足指定類(lèi)型的格式,例如我們不可以將 “省份名” 字段設置為 整數型)。使用 Pandas 讀取這個(gè) Excel 數據,代碼和輸出如下:
  #?數據存儲的路徑<br />path?=?'./5G?產(chǎn)業(yè)全國各省市分年度專(zhuān)利申請、專(zhuān)利授權情況(2000-2019.9).xlsx'<br />#?這里指定字段的數據類(lèi)型<br />columns_type?=?{'年份':'str',?<br />????????????????'省份名':'str',?<br />????????????????'省份行政代碼':'int',?????????????????????????????????<br />????????????????'專(zhuān)利申請':'int',?<br />????????????????'專(zhuān)利授權':'int',?<br />????????????????'專(zhuān)利類(lèi)型':'str'}<br />#?dtype?參數用于指定字段的類(lèi)型,如果不需要特意指定字段的類(lèi)型,不使用?dtype?參數即可<br />data?=?pd.read_excel(path,?dtype=columns_type)<br />data<br />
  
  讀取數據后我們使用 Pandas 中的相關(guān)方法生成一個(gè)新的列,這一列中的數據是一個(gè)包含專(zhuān)利申請、專(zhuān)利授權和專(zhuān)利類(lèi)型的列表。操作代碼和新生成的數據如下:
  #?根據專(zhuān)利申請、專(zhuān)利授權和專(zhuān)利類(lèi)型三個(gè)字段得到一個(gè)新字段<br />data['列表']?=?data.apply(lambda?X:?[X['專(zhuān)利申請'],?X['專(zhuān)利授權'],?X['專(zhuān)利類(lèi)型']]?,axis=1)<br />data<br />
  
  將新生成的數據保存為 csv 文件后再讀取,讀取時(shí)我們故意將部分字段讀取為錯誤的類(lèi)型,隨后使用錯誤的數據來(lái)給大家演示如何進(jìn)行數據類(lèi)型的轉換。
  #?將剛剛新生成的數據保存為?csv?文件<br />#?參數 index=False 的含義是,不講數據索引寫(xiě)入 csv 文件中<br />data.to_csv('新數據.csv',?index=False)<br /><br />#?使用錯誤的字段類(lèi)型重新讀取數據<br />#?我們將年份讀取為浮點(diǎn)型(小數型),將專(zhuān)利申請讀取為字符型<br />wrong_type?=?{'年份':'float',???????????????????????????????????<br />??????????????'專(zhuān)利申請':'str'}<br />DATA?=?pd.read_csv('新數據.csv',?dtype=wrong_type)<br /><br />#?查看專(zhuān)利申請字段類(lèi)型<br />print(DATA.專(zhuān)利申請.dtype)??#?輸出:object,說(shuō)明該字段含有字符型數據<br />DATA<br />
  
  可以看到,“年份” 字段中所有的年份都變?yōu)樾敌?;通過(guò)代碼也判斷出 “專(zhuān)利申請” 字段不再是整數型,而是字符型,因為 DataFrame 中的字符型數據不會(huì )顯示兩端的引號,所以無(wú)法目測其類(lèi)型。那么這種內容為數字的字符型數據會(huì )給我們什么麻煩呢?假設我們需要使用 專(zhuān)利授權/ 專(zhuān)利申請 來(lái)計算專(zhuān)利授權率時(shí) ,會(huì )發(fā)現整數和字符之間無(wú)法運算。如果這兩個(gè)字段中的值的都是字符型,那么兩者只能進(jìn)行加法運算,例如:“45” + “8” == “458”,這恐怕更不是我們想要的結果。接下來(lái)我們使用數據類(lèi)型轉換的方法來(lái)糾正這些錯誤的數據。1使用 astype() 轉換基本類(lèi)型Pandas 專(zhuān)門(mén)為類(lèi)型轉換提供了一個(gè) astype() 方法,這個(gè)方法可以將數據類(lèi)型轉換為希望的類(lèi)型,既可以操作 Series,又可以操作 DataFrame,使用時(shí)只需要傳入轉換后的類(lèi)型即可。我們在往期的文章中提到過(guò),Pandas 中絕大多數涉及到數據修改的方法,他們都不會(huì )直接修改原始的數據,而是返回一個(gè)新的數據。astype()也是一樣的,默認返回一個(gè)新的數據。場(chǎng)景 1:將數據中的年份字段轉換為整數型
  #?將字段類(lèi)型由浮點(diǎn)型(小數型)轉換為整數型?int<br />#?返回一個(gè)新數據,調用該方法的是一個(gè)?Series,返回值也將是一個(gè)?Series<br />DATA['年份'].astype(int)<br />
  
  希望類(lèi)型轉換操作在原始數據中生效可以使用下面的代碼。
  #?將新生的數據重新賦值給原始數據即可<br />#?賦值操作不會(huì )返回任何值<br />DATA['年份']?=?DATA['年份'].astype(int)<br />#?輸出查看轉換后的數據<br />DATA<br />
  
  場(chǎng)景 2:將數據中所有內容轉換為字符型數據,轉換后的數據命名為ALL_STR
  #?將類(lèi)型轉換為字符型數據后的新數據命名為?ALL_STR<br />ALL_STR?=?DATA.astype(str)<br />#?查看新數據的信息<br />ALL_STR.info()<br />
  
  所有的字段類(lèi)型都變?yōu)?object,說(shuō)明所有字段中都含有字符型數據,操作生效。另外,當字段中存在無(wú)法轉換的數據值時(shí),可以指定參數 errors='ignore' 來(lái)忽略無(wú)法轉換的數據值。假如我們希望將所有字段都轉換為浮點(diǎn)型(小數型),但是字符型數據 “北京” 、“45”、“發(fā)明專(zhuān)利” 等字符型數據無(wú)法轉換為浮點(diǎn)型,我們則可以使用下面的代碼來(lái)轉換可以轉換的字段:
  #?指定參數?errors='ignore',忽略無(wú)法轉換的數據值<br />DATA.astype(float,?errors='ignore')<br />
  
  可以看到,除了一些字符型數據之外,其他的數字類(lèi)型數據都被轉換為浮點(diǎn)型(小數型)數據。同樣地,如果不進(jìn)行賦值操作,那么就會(huì )返回一個(gè)新的數據,而原始數據不會(huì )發(fā)生變化。2使用 eval() 轉換特殊類(lèi)型astype() 方法多用于浮點(diǎn)型 float、整數型 int 和 字符型 str 的轉換操作。當涉及到字符型轉化為列表,字典等 Python 的組合數據類(lèi)型時(shí),則需要使用 Python 自帶的方法 eval() 。該函數可以去掉字符串最外側的引號,并按照 Python 語(yǔ)句方式執行去掉引號后的字符內容。下面我們舉例介紹一下 eval() 的用法。
  #?對字符串?'12'?做轉換<br />eval('12')?????#?得到整數:12<br /><br />#?對字符串?'12.5'?做轉換<br />eval('12.5')???#?得到浮點(diǎn)數:12.5<br /><br />#?對字符串?'12+5'?做轉換<br />eval('12+5')???#?得到整數:17<br /><br />#?定義變量?a?后對字符串?'a'?做轉換<br />a?=?'20'<br />eval('a')??????#?得到 a 的值:20<br /><br />#?對字符串?"[11,12,'列表元素']"?做轉換<br />eval("[11,12,'列表元素']")?#?得到列表:[11, 12, '列表元素']<br /><br />#?定義變量?m,n?后對字符串?'[m,n,m-50]'?做轉換<br />m=100<br />n='某個(gè)字符串'<br />eval("[m,n,m-50]")??#?得到列表:[100, '某個(gè)字符串', 50]<br />
  根據上面的例子可以看出,eval() 確實(shí)可以去掉字符串最外側的引號,并按照 Python 語(yǔ)句方式執行去掉引號后的字符內容。這個(gè)方法不僅可以轉換列表形式的字符串,對諸如字典、元組以及集合等 Python 數據類(lèi)型形式的字符串,該方法依然可用。場(chǎng)景 3:將數據中“列表”字段轉換為 Python 列表類(lèi)型由于 eval() 方法操作的是字符串對象,一次只接受一個(gè)需要轉化的對象,當需要使用它來(lái)對 DataFrame 的一整個(gè)字段做轉換操作時(shí),需要借助循環(huán)或者其他的 Pandas 方法。
  #?輸出查看轉換之前"列表"字段最后一個(gè)值的類(lèi)型,原始的類(lèi)型為?str?型<br />print(type(DATA['列表'].values[-1]))<br />#?輸出:,確認是字符型<br /><br />#?方法 1:借助 for 循環(huán)<br />for?i?in?DATA.index:<br />????#?遍歷數據的索引<br />????#?根據索引找到待轉換的數據<br />????Target?=?DATA.loc[i,'列表']<br />????#?將轉換后的數據重新賦值給原來(lái)位置的數據值<br />????DATA['列表'][i]?=?eval(Target)<br />????<br />#?輸出查看"列表"字段最后一個(gè)值的類(lèi)型,若為列表,說(shuō)明轉換成功<br />print(type(DATA['列表'].values[-1]))<br />#?輸出:,轉換成功<br /><br />#?方法 2:借助 Pandas 方法 map()。不再輸出查看類(lèi)型<br />DATA['列表']?=?DATA['列表'].map(eval)<br /><br />#?方法 3:借助 Pandas 方法 apply()。不再輸出查看類(lèi)型<br />DATA['列表']?=?DATA['列表'].apply(eval)<br />
  后面兩種方法可以實(shí)現 方法 1 同樣的效果,且代碼量更少。Part4總結本期文章中,我們介紹了數據類(lèi)型錯誤帶來(lái)的影響,同時(shí)也介紹了轉換字段數據類(lèi)型的方法。使用類(lèi)型轉換方法可以在基本的數據類(lèi)型之間進(jìn)行合理的轉換。同時(shí)也介紹了轉換特殊數據類(lèi)型的方法。學(xué)習這些可以讓我們靈活地轉換數據的類(lèi)型,避免類(lèi)型錯亂帶來(lái)的麻煩。在最后的 場(chǎng)景3中,我們使用了map() 和 apply() 兩個(gè)方法,使用更少的代碼完成了同樣的功能。下期文章我們將會(huì )繼續介紹 Pandas,學(xué)習如何使用以上兩種方法來(lái)根據已有的數據生成新的數據列(數據列衍生)。
  

Crack App | 某搜索 App 中關(guān)于 x 信文章檢索功能的加密參數

采集交流 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 123 次瀏覽 ? 2022-04-30 02:25 ? 來(lái)自相關(guān)話(huà)題

  Crack App | 某搜索 App 中關(guān)于 x 信文章檢索功能的加密參數
  點(diǎn)擊上方“咸魚(yú)學(xué)Python”,選擇“加為星標”
  第一時(shí)間關(guān)注Python技術(shù)干貨!
  
  圖源:極簡(jiǎn)壁紙
  今日目標
  今天的目標是很多讀者朋友在采集微信文章時(shí)常用站的 app 版本
  aHR0cHM6Ly93d3cud2FuZG91amlhLmNvbS9zZWFyY2gvNjU1NTQ3NDYwMzMwMTAyMDk0MQ==
  抓包分析
  抓包使用的是 Charles + Postern 的組合
  使用大黃鳥(niǎo) app 抓包也是可以的,Charles 看著(zhù)會(huì )更舒服一些
  打開(kāi) app 搜索任意內容,切換到微信欄目就可以抓到以下的請求包了
  
  點(diǎn)擊這個(gè)請求可以看到請求參數還有請求的結果都是加密的
  
  請求的參數是k、v、u、r、g、p的名字,所以通過(guò)參數名檢索的方法很難定位到很準確的結果
  靜態(tài)分析定位邏輯
  apk 包推薦使用 jadx 1.2 打開(kāi),用 1.3 搜索的時(shí)候老是崩潰
  通過(guò)以請求鏈接的部分v2.get作為搜索關(guān)鍵詞可以定位到下面的搜索結果
  
  最后一個(gè)搜索的結果和我們的請求鏈接最匹配
  點(diǎn)進(jìn)去可以看到下面的內容
  
  可以看到圖中紅框的部分應該是請求的部分,紅框下面是返回的部分
  分別經(jīng)過(guò)了encrypt和decrypt兩個(gè)方法
  先講講我是怎么確定是這兩個(gè)方法的
  紅框部分中定義了一個(gè)hashMap,通其中put了一個(gè)Content-Length,這個(gè)搞過(guò) js 逆向的都知道,這個(gè)是代表了請求提交內容的長(cháng)度
  這個(gè)長(cháng)度是通過(guò)encrypt.length得到的,而encrypt是通過(guò)ScEncryptWall.encrypt(str, str2, str3);得到的
  而返回部分的代碼是在判斷了f0.b得出的,在f0.b的判斷中有一關(guān)于response success的輸出,進(jìn)一步確認了我們的判斷
  所以這里的encrypt和decrypt兩個(gè)方法是分析的重點(diǎn)
  進(jìn)一步追進(jìn)去可以看到這兩個(gè)方法都是native方法,定義在libSCoreTools.so里面
  
  動(dòng)態(tài)調試確認邏輯
  既然是 native 方法,通過(guò) IDA 分析這幾個(gè)也是導出方法,這里 hook 的方法就很多了。
  
  我們直接用frida hook看下出入參看看是不是符合我們在上一部分的猜想
  先看encrypt
  function?hook_encrypt(){<br />????Java.perform(function?()?{<br />????????var?ScEncryptWall?=?Java.use('包名.類(lèi)名');<br />????????ScEncryptWall.encrypt.implementation?=?function?(str1,str2,str3)?{<br />????????????console.log('str1:?',?str1);<br />????????????console.log('str2:?',?str2);<br />????????????console.log('str3:?',?str3);<br />????????????var?res?=?this.encrypt(str1,?str2,?str3);<br />????????????console.log('res:?',?res);<br />????????????return?res;<br />????????}<br />????})<br />}<br />setImmediate(hook_encrypt)<br />
  
  通過(guò)hook可以得到以下結果
  str1?=?請求的?url<br />str2?=?請求提交的參數(明文)<br />str3?=?空<br />
  返回的結果就是加密好的參數了
  同樣的hook decrypt
  function?hook_decrypt(){<br />????Java.perform(function?()?{<br />????????var?ScEncryptWall?=?Java.use('包名.類(lèi)名');<br />????????ScEncryptWall.decrypt.implementation?=?function?(data)?{<br />????????????console.log('data:?',?data);<br />????????????var?res?=?this.decrypt(a);<br />????????????console.log('res:?',?Java.use('java.lang.String').$new(res));<br />????????????return?res;<br />????????}<br />????})<br />}<br />setImmediate(hook_decrypt)<br />
  打印結果如下
  
  參數是請求的返回值,解密的結果是列表頁(yè)的內容
  完事~,Python RPC 調用一下就可以爽爽的采集相關(guān)的文章了 查看全部

  Crack App | 某搜索 App 中關(guān)于 x 信文章檢索功能的加密參數
  點(diǎn)擊上方“咸魚(yú)學(xué)Python”,選擇“加為星標”
  第一時(shí)間關(guān)注Python技術(shù)干貨!
  
  圖源:極簡(jiǎn)壁紙
  今日目標
  今天的目標是很多讀者朋友在采集微信文章時(shí)常用站的 app 版本
  aHR0cHM6Ly93d3cud2FuZG91amlhLmNvbS9zZWFyY2gvNjU1NTQ3NDYwMzMwMTAyMDk0MQ==
  抓包分析
  抓包使用的是 Charles + Postern 的組合
  使用大黃鳥(niǎo) app 抓包也是可以的,Charles 看著(zhù)會(huì )更舒服一些
  打開(kāi) app 搜索任意內容,切換到微信欄目就可以抓到以下的請求包了
  
  點(diǎn)擊這個(gè)請求可以看到請求參數還有請求的結果都是加密的
  
  請求的參數是k、v、u、r、g、p的名字,所以通過(guò)參數名檢索的方法很難定位到很準確的結果
  靜態(tài)分析定位邏輯
  apk 包推薦使用 jadx 1.2 打開(kāi),用 1.3 搜索的時(shí)候老是崩潰
  通過(guò)以請求鏈接的部分v2.get作為搜索關(guān)鍵詞可以定位到下面的搜索結果
  
  最后一個(gè)搜索的結果和我們的請求鏈接最匹配
  點(diǎn)進(jìn)去可以看到下面的內容
  
  可以看到圖中紅框的部分應該是請求的部分,紅框下面是返回的部分
  分別經(jīng)過(guò)了encrypt和decrypt兩個(gè)方法
  先講講我是怎么確定是這兩個(gè)方法的
  紅框部分中定義了一個(gè)hashMap,通其中put了一個(gè)Content-Length,這個(gè)搞過(guò) js 逆向的都知道,這個(gè)是代表了請求提交內容的長(cháng)度
  這個(gè)長(cháng)度是通過(guò)encrypt.length得到的,而encrypt是通過(guò)ScEncryptWall.encrypt(str, str2, str3);得到的
  而返回部分的代碼是在判斷了f0.b得出的,在f0.b的判斷中有一關(guān)于response success的輸出,進(jìn)一步確認了我們的判斷
  所以這里的encrypt和decrypt兩個(gè)方法是分析的重點(diǎn)
  進(jìn)一步追進(jìn)去可以看到這兩個(gè)方法都是native方法,定義在libSCoreTools.so里面
  
  動(dòng)態(tài)調試確認邏輯
  既然是 native 方法,通過(guò) IDA 分析這幾個(gè)也是導出方法,這里 hook 的方法就很多了。
  
  我們直接用frida hook看下出入參看看是不是符合我們在上一部分的猜想
  先看encrypt
  function?hook_encrypt(){<br />????Java.perform(function?()?{<br />????????var?ScEncryptWall?=?Java.use('包名.類(lèi)名');<br />????????ScEncryptWall.encrypt.implementation?=?function?(str1,str2,str3)?{<br />????????????console.log('str1:?',?str1);<br />????????????console.log('str2:?',?str2);<br />????????????console.log('str3:?',?str3);<br />????????????var?res?=?this.encrypt(str1,?str2,?str3);<br />????????????console.log('res:?',?res);<br />????????????return?res;<br />????????}<br />????})<br />}<br />setImmediate(hook_encrypt)<br />
  
  通過(guò)hook可以得到以下結果
  str1?=?請求的?url<br />str2?=?請求提交的參數(明文)<br />str3?=?空<br />
  返回的結果就是加密好的參數了
  同樣的hook decrypt
  function?hook_decrypt(){<br />????Java.perform(function?()?{<br />????????var?ScEncryptWall?=?Java.use('包名.類(lèi)名');<br />????????ScEncryptWall.decrypt.implementation?=?function?(data)?{<br />????????????console.log('data:?',?data);<br />????????????var?res?=?this.decrypt(a);<br />????????????console.log('res:?',?Java.use('java.lang.String').$new(res));<br />????????????return?res;<br />????????}<br />????})<br />}<br />setImmediate(hook_decrypt)<br />
  打印結果如下
  
  參數是請求的返回值,解密的結果是列表頁(yè)的內容
  完事~,Python RPC 調用一下就可以爽爽的采集相關(guān)的文章了

微信公眾號視頻批量下載軟件--視頻批量下載的方法

采集交流 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 395 次瀏覽 ? 2022-04-29 14:13 ? 來(lái)自相關(guān)話(huà)題

  微信公眾號視頻批量下載軟件--視頻批量下載的方法
  大家好,這是余夫第 011篇原創(chuàng )文章,關(guān)注余夫持續分享實(shí)用軟件和各種實(shí)用資料,第一時(shí)間獲取更多的軟件和資料。
  注意本公眾號介紹的所有下載視頻的軟件,視頻下載的前提是你的視頻必須是已經(jīng)付費購買(mǎi)了課程或者是免費視頻,只有可以正常播放才能下載。
  微信公眾號的視頻分為兩種
  一種是自己上傳到微信公眾號里面的視頻,以我自己的公眾號視頻為例如下圖
  
  這種就是直接上傳到公眾號里面的原創(chuàng )視頻,這種視頻可以直接復制鏈接到瀏覽器里面通過(guò)插件可以直接下載。
  這個(gè)文章介紹的下載方法就可以實(shí)現單個(gè)下載
  視頻少的話(huà)可以用上面單個(gè)的一個(gè)一個(gè)的下載,那要是上百個(gè)視頻就需要使用批量下載了。
  
  
  這樣直接就可以批量下載速度很快100個(gè)視頻也就是幾分鐘的事。有需要下載的可以聯(lián)系我代下載。
  另外一種是調用的騰訊視頻的鏈接,如下面這種就是調用騰訊視頻。
  
  這種的可以直接復制鏈接到瀏覽器里面里面去播放,選擇分辨率高的來(lái)播放,idm的插件也可以直接識別到點(diǎn)擊下載就可以了。
  也可以批量采集鏈接復制到軟件里面來(lái)下載。使用爬蟲(chóng)插件直接批量獲取鏈接
  
  
  直接復制鏈接到軟件里面就可以實(shí)現批量下載了。
  
  這樣就把公眾號的視頻下載下來(lái)了。 音頻是樣的道理,文章也是可以下載,過(guò)2天講下文章怎么下載的。 查看全部

  微信公眾號視頻批量下載軟件--視頻批量下載的方法
  大家好,這是余夫第 011篇原創(chuàng )文章,關(guān)注余夫持續分享實(shí)用軟件和各種實(shí)用資料,第一時(shí)間獲取更多的軟件和資料。
  注意本公眾號介紹的所有下載視頻的軟件,視頻下載的前提是你的視頻必須是已經(jīng)付費購買(mǎi)了課程或者是免費視頻,只有可以正常播放才能下載。
  微信公眾號的視頻分為兩種
  一種是自己上傳到微信公眾號里面的視頻,以我自己的公眾號視頻為例如下圖
  
  這種就是直接上傳到公眾號里面的原創(chuàng )視頻,這種視頻可以直接復制鏈接到瀏覽器里面通過(guò)插件可以直接下載。
  這個(gè)文章介紹的下載方法就可以實(shí)現單個(gè)下載
  視頻少的話(huà)可以用上面單個(gè)的一個(gè)一個(gè)的下載,那要是上百個(gè)視頻就需要使用批量下載了。
  
  
  這樣直接就可以批量下載速度很快100個(gè)視頻也就是幾分鐘的事。有需要下載的可以聯(lián)系我代下載。
  另外一種是調用的騰訊視頻的鏈接,如下面這種就是調用騰訊視頻。
  
  這種的可以直接復制鏈接到瀏覽器里面里面去播放,選擇分辨率高的來(lái)播放,idm的插件也可以直接識別到點(diǎn)擊下載就可以了。
  也可以批量采集鏈接復制到軟件里面來(lái)下載。使用爬蟲(chóng)插件直接批量獲取鏈接
  
  
  直接復制鏈接到軟件里面就可以實(shí)現批量下載了。
  
  這樣就把公眾號的視頻下載下來(lái)了。 音頻是樣的道理,文章也是可以下載,過(guò)2天講下文章怎么下載的。

調用鏈追蹤系統在伴魚(yú):Opentelemetry最佳實(shí)踐案例分享

采集交流 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 111 次瀏覽 ? 2022-04-29 14:06 ? 來(lái)自相關(guān)話(huà)題

  調用鏈追蹤系統在伴魚(yú):Opentelemetry最佳實(shí)踐案例分享
  搭建可靠的鏈路追蹤系統
  在正式介紹前,簡(jiǎn)單交代一下背景:2015 年,在伴魚(yú)服務(wù)端起步之時(shí),技術(shù)團隊就做出統一使用 Go 語(yǔ)言的決定。這個(gè)決定的影響主要體現在:
  早期實(shí)踐對接 Jaeger
  2019 年,公司內部的微服務(wù)數量逐步增加,調用關(guān)系日趨復雜,工程師做性能分析、問(wèn)題排查的難度變大。這時(shí)亟需一套調用鏈追蹤系統幫助我們增強對服務(wù)端全貌的了解。經(jīng)過(guò)調研后,我們決定采用同樣基于 Go 語(yǔ)言搭建的、由 CNCF 孵化的項目Jaeger。當時(shí),服務(wù)的開(kāi)發(fā)和治理都尚未引入 context,不論進(jìn)程內部調用還是跨進(jìn)程調用,都沒(méi)有上下文傳遞。因此早期引入調用鏈追蹤的工作重心就落在了服務(wù)及服務(wù)治理框架的改造,包括:
  部署方面:測試環(huán)境采用 all-in-one,線(xiàn)上環(huán)境采用 direct-to-storage 方案。整個(gè)過(guò)程前后大約耗時(shí)一個(gè)月,我們在 2019 年 Q3 上線(xiàn)了第一版調用鏈追蹤系統。配合廣泛被采用的 prometheus + grafana 以及 ELK,我們在微服務(wù)群的可觀(guān)測性上終于湊齊了調用鏈 (traces)、日志 (logs) 和監控指標 (metrics) 三個(gè)要素。
  下圖是第一版調用鏈追蹤系統的數據上報通路示意圖。服務(wù)運行在容器中,通過(guò) opentracing 的 sdk 埋點(diǎn),Jaeger 的 go-sdk 上報到宿主機上的 Jaeger-agent,后者再將數據進(jìn)一步上報到 Jaeger-collector,最終將調用鏈數據寫(xiě)入 ES,建立索引,即圖中的 Jaeger backends。
  
  遇到的問(wèn)題
  Jaeger 支持三種采樣方式:
  調用鏈通路改造使用場(chǎng)景
  2020 年,我們不斷收到業(yè)務(wù)研發(fā)的反饋:能不能全量采集 trace?
  這促使我們開(kāi)始重新思考如何改進(jìn)調用鏈追蹤系統。我們做了一個(gè)簡(jiǎn)單的容量預估:目前 Jaeger 每天寫(xiě)入 ES 的數據量接近 100GB/天,如果要全量采集 trace 數據,保守假設平均每個(gè) HTTP API 服務(wù)的總 QPS 為 100,那么完整存下全量數據需要 10TB/天;樂(lè )觀(guān)假設 100 名服務(wù)器研發(fā)每人每天查看 1 條 trace,每條 trace 的平均大小為 1KB,則整體信噪比千萬(wàn)分之一??梢钥闯?,這件事情本身的 ROI 很低,考慮到未來(lái)業(yè)務(wù)會(huì )持續增長(cháng),存儲這些數據的價(jià)值也會(huì )繼續降低,因此全量采集的方案被放棄。退一步想:全量采集真的是本質(zhì)需求嗎?實(shí)際上并非如此,我們想要的其實(shí)是「有意思」的 trace 全采,「沒(méi)意思」的 trace 不采。
  根據 理論篇 中介紹的應用場(chǎng)景,實(shí)際上第一版調用鏈追蹤系統只支持了穩態(tài)分析,而業(yè)務(wù)研發(fā)亟需的是異常檢測。要同時(shí)支持這兩種場(chǎng)景,我們必須借助尾部連貫采樣 (tail-based coherent sampling)。相對于頭部連貫采樣在第一個(gè) span 處就做出是否采樣的決定,尾部連貫采樣可以讓我們在獲取 (接近) 完整的 trace 信息后再做出判斷。理想情況下,只要能合理地制定采樣的判斷邏輯,我們的調用鏈追蹤系統就能做到「有意思」的 trace 全采,「沒(méi)意思」的 trace 不采。
  架構設計
  Jaeger 團隊從 2017 年就開(kāi)始討論引入 tail-based sampling 的可能性,但至今未有定論。在一次與 Jaeger 工程師 jpkrohling 的一對一溝通中,對方也證實(shí)了目前 Jaeger 尚沒(méi)有相關(guān)的支持計劃。因此,我們不得不另辟蹊徑。經(jīng)過(guò)一番調研,我們找到了剛剛進(jìn)駐 CNCF SandBox 的OpenTelemetry,它的opentelemetry-collector子項目恰好能支持我們在現有架構上引入尾部連貫采樣。
  OpenTelemetry Collector
  整個(gè) OpenTelemetry 項目目的在于統一市面上可觀(guān)測性數據 (telemetry data) 的標準,同時(shí)提供推動(dòng)這些標準實(shí)施的組件和工具。opentelemetry-collector 就是這個(gè)生態(tài)中的一個(gè)重要組件,它的架構圖如下:
  
  collector 內部有 4 個(gè)核心組件:
  opentelemetry-collector 項目被拆成兩部分:主項目 opentelemetry-collector 和社區貢獻項目 opentelemetry-collector-contrib,前者負責管理核心邏輯、數據結構以及通用的 Receivers、Processors、Exporters、Extensions 實(shí)現,后者則負責接收一些社區貢獻的組件,當然貢獻者主要都來(lái)自于可觀(guān)測性 SaaS 解決方案供應商,如 DataDog、Splunk、LightStep 以及一些公有云廠(chǎng)商。opentelemtry-collector 項目的插件化管理方式,使得定制化開(kāi)發(fā) Receiver、Processor、Exporter 的成本很低,我們在做概念驗證時(shí),基本可以在一兩個(gè)小時(shí)內開(kāi)發(fā)并測試完畢一個(gè)組件。除此之外,opentelemetry-collector-contrib 還提供了開(kāi)箱即用的tailsamplingprocessor。
  由于 opentelemetry-collector 是 OpenTelemetry 團隊推動(dòng)標準實(shí)施的重要組件,且 OpenTelemetry 本身并沒(méi)有提供獨立的數據存儲、索引實(shí)現的計劃,因此它在與市面上流行的調用鏈追蹤框架,如 Zipkin、Jaeger、OpenCensus,的兼容性上下了很大功夫。通過(guò) Receivers 和 Exporters 的使用,我們可以用它替換 jaeger-agent,也可以放在 jaeger-agent 與 jaeger-collector 之間,必要時(shí)還可以在 jaeger-agent 和 jaeger-collector 之間部署多層 collectors。除此之外,如果有一天想換掉 jaeger-backend,比如新發(fā)布的 Grafana Tempo,我們也能很輕松的完成,并且利用多個(gè) Pipelines 或一個(gè) Pipeline 多個(gè) Exporters 灰度上線(xiàn),逐步替換。
  上報通路
  基于以上的調研和現有的架構,我們設計了第二版調用鏈追蹤的架構,如下圖所示:
  
  用一組 opentelemetry-collector 替換 jaeger-agent,即圖中的 otel-agent;同時(shí)在 otel-agent 與 jaeger-collector 之間增加另一組 opentelemetry-collector,即圖中的 otel-collector。otel-agent 收集宿主機上不同服務(wù)上報的 trace 數據,打包批量發(fā)送給 otel-collector,后者負責做尾部連貫采樣,將「有意思」的 trace 繼續輸出到原始架構中的 jaeger-collector,后者負責將數據投入 ElasticSearch 中,建立索引。
  這里還有一個(gè)問(wèn)題需要解決:整個(gè)架構做到高可用,勢必要部署多個(gè) otel-collector 實(shí)例,如果使用簡(jiǎn)單的負載均衡策略,不同 otel-agents、以及單個(gè) otel-agent 不同時(shí)刻上報的數據,可能被隨機上報到某個(gè) otel-collector 實(shí)例,這就意味著(zhù),同一個(gè) trace 的不同 spans 無(wú)法集中到同一個(gè) otel-collector 實(shí)例上,既會(huì )導致同一個(gè) trace 的不同 spans 的決定不一致,即不是連貫采樣;也會(huì )導致尾部采樣時(shí)提供判斷的數據不全。解決方案很簡(jiǎn)單:讓 otel-agent 按照 traceID 做負載均衡。
  在調研階段我們正好看到 opentelemetry-collector 社區也有此支持計劃,并且前面提到的工程師 jpkrohling 正在通過(guò)增加loadbalancingexporter解決它,雖然直接使用 bleeding edge 的版本有一定的風(fēng)險,我們還是決定嘗試。在概念驗證階段,我們也的確發(fā)現了新功能的若干問(wèn)題,但通過(guò)反饋的方式一一解決,最終獲得了可以按預期執行尾部連貫采樣的調用鏈追蹤系統。
  采樣規則
  尾部連貫采樣的數據通路已經(jīng)準備就緒,下一步就是確定和實(shí)施采樣規則。
  「有意思」的調用鏈
  什么是「有意思」的調用鏈?研發(fā)在分析、排障過(guò)程中想查詢(xún)的任何調用鏈就是「有意思」的調用鏈。但落實(shí)到代碼的必須是確定性的規則,根據日常排障經(jīng)驗,我們先確定了以下三種情形:
  滿(mǎn)足任意條件,就認為這個(gè)調用鏈「有意思」。在伴魚(yú),只要服務(wù)打印了 ERROR 級別的日志就會(huì )觸發(fā)報警,研發(fā)人員就會(huì )收到 im 消息或電話(huà)報警,如果能保證觸發(fā)報警的調用鏈數據必采,研發(fā)人員的排障體驗就會(huì )有很大的提升;我們的 DBA 團隊認為超過(guò) 200ms 的查詢(xún)請求都被判定為慢查詢(xún),如果能保證這些請求的調用鏈必采,就能大大方便研發(fā)排查導致慢查詢(xún)的請求;對于在線(xiàn)服務(wù)來(lái)說(shuō),時(shí)延過(guò)高會(huì )令用戶(hù)體驗下降,但具體高到什么程度會(huì )引發(fā)明顯的體驗下降我們暫時(shí)沒(méi)有數據支撐,因此先配置為 1s,支持隨時(shí)修改閾值。
  當然,以上條件并不絕對,我們可以在之后的實(shí)踐根據反饋調整、新增規則,如單個(gè)請求引起的數據庫、緩存查詢(xún)次數超過(guò)某閾值等。
  采樣流水線(xiàn)
  在第二版系統中,我們期望同時(shí)支持穩態(tài)分析與異常檢測,因此采樣過(guò)程既要按概率或限流方式采集一部分 trace,也需要按上文擬定的「有意思」 規則采集令一部分 trace。截止到本文撰寫(xiě)前,tailsamplingprocessor支持 4 種策略:
  「按概率或限流采集一部分 trace」可以利用rate_limiting實(shí)現嗎?rate_limiting只能按照每秒通過(guò)的 spans 個(gè)數限流,但 spans 數量在高峰期、低峰期、業(yè)務(wù)所處階段都不一樣,每個(gè) trace 的平均 spans 數量也會(huì )隨著(zhù)微服務(wù)群規模以及依賴(lài)關(guān)系發(fā)生變化,因此設置 spans_per_second 將讓我們很難對這個(gè)參數的最終效果合理評估,因此直接使用rate_limiting的方案被否決。
  「按規則采集另一部分 trace」可以直接使用numeric_attribute和string_attribute實(shí)現嗎?span 中還存在布爾 (bool) 類(lèi)型的 tag,以「在調用鏈上如果打印了 ERROR 級別日志」為例,按照規范我們會(huì )記錄span.SetTag("error" , true),但 tailsamplingprocessor 并未支持bool_attribute;此外,未來(lái)我們可能會(huì )有更復雜的組合條件,這時(shí)僅靠numeric_attribute和string_attribute也無(wú)法實(shí)現。
  經(jīng)過(guò)再三分析,我們最終決定利用 Processors 的鏈式結構,組合多個(gè) Processor 完成采樣,流水線(xiàn)如下圖所示:
  
  其中probattr負責在 trace 級別按概率抽樣,anomaly 負責分析每個(gè) trace 是否符合「有意思」的規則,如果命中二者之一,trace 就會(huì )被打上標記,即sampling.priority。最后在tailsamplingprocessor上配置一條規則即可,如下所示:
  tail_sampling:<br />???policies:<br />?????[<br />???????{<br />?????????name:?sample_with_high_priority,<br />?????????type:?numeric_attribute,<br />?????????numeric_attribute:?{?key:?"sampling.priority",?min_value:?1,?max_value:?1?}<br />???????}<br />?????]
  這里sampling.priority是整數類(lèi)型,當前取值只有 0 和 1。按上面的配置,所以sampling.priority = 1的trace 都會(huì )被采集。后期可以增加更多的采集優(yōu)先級,在必要的時(shí)候可以多采樣 (upsampling) 或降采樣 (downsampling)。
  部署實(shí)施
  采樣規則確立后,整個(gè)解決方案就已跑通,下一步就是進(jìn)入部署實(shí)施階段。
  上線(xiàn)準備基礎庫改造
  動(dòng)態(tài)更新 Tracer在第一版系統中,每個(gè)進(jìn)程啟動(dòng)時(shí)會(huì )從 apollo 上獲取采樣配置,傳遞給 Jaeger sdk,后者利用配置初始化 GlobalTracer。GlobalTracer 會(huì )在 trace 的第一個(gè) span 出現時(shí),決定是否采集,并把這個(gè)決定傳遞下去,即頭部連貫采樣。在實(shí)施新架構時(shí),我們需要 Jaeger sdk 將所有 trace 數據盡數上報。為了讓這個(gè)過(guò)程更加平滑,我們對 Jaeger sdk 配置做出兩方面改造:
  支持對每個(gè)服務(wù)下發(fā)不同的采樣配置,方便灰度發(fā)布 支持動(dòng)態(tài)更新采樣配置,使采樣策略配置不依賴(lài)發(fā)布
  日志庫改造為了保證打印過(guò) ERROR 級別日志的調用鏈必采,我們也在通用日志庫的相應位置上給 span 打上 error 標簽。
  監控看板配置
  opentelemetry-collector 內部利用 OpenCensus sdk 埋了很多有用的監控指標,并按照 Open Metrics 規范暴露數據。因為指標數量并不多,我們將大多數指標都配置了到 Grafana 看板中,包括:
  xxx_receiver_accepted/refused_spans這里的 xxx 指代任意一個(gè) pipeline 中使用的 receiver。實(shí)際上這里有兩個(gè)具體指標:receiver 接收的 spans 數量和 receiver 拒絕的 spans 數量。二者可以與其它指標結合,分析系統在當前狀況下的入口流量瓶頸。
  xxx_exporter_send(failed)_spans這里的 xxx 指代任意一個(gè) pipeline 中使用的 exporter。實(shí)際上這里有兩個(gè)具體指標:exporter 發(fā)送成功的 spans 數量和 exporter 發(fā)送失敗的 spans 數量。二者可以與其它指標結合,分析系統在當前狀況下的出口流量瓶頸。
  otelcol_processor_tail_sampling_sampling_trace_dropped_too_early要介紹上面這個(gè)指標,需要簡(jiǎn)單了解tailsamplingprocessor的工作原理。在分布式環(huán)境中,tailsamplingprocessor永遠無(wú)法確定一個(gè) trace 的所有 spans 在當前時(shí)刻是否收集完畢,因此需要設置一個(gè)超時(shí)時(shí)間,即 這里 的decision_wait,下面假設decision_wait = 5s。Trace Data 進(jìn)入 processor 后,會(huì )被分別放入兩個(gè)數據結構:
  
  一個(gè)固定大小的隊列和一個(gè)哈希表,二者合起來(lái)實(shí)現 trace data 的 LRU cache。同時(shí) processor 會(huì )將所有進(jìn)入到其中的 traces 按照每秒一個(gè) batch 組織起來(lái),內部一共維持 5 個(gè) batch (decision_wait)。每隔一秒鐘,將最老的 batch 取出來(lái),對其中的 traces 分別判斷是否符合采樣規則,符合則將其傳遞給后續的 processors:
  
  如果在做采樣決策時(shí),發(fā)現相應的 trace 已經(jīng)被 LRU cache 清出,則認為「trace dropped too early」,后者意味著(zhù)tailsamplingprocessor已經(jīng)超負荷。理論上這個(gè)指標如果不等于 0,尾部連貫采樣功能就處于異常狀態(tài)。
  灰度方案
  上文提到過(guò),實(shí)施改造需要讓 Jaeger sdk 全量上報 trace。由于「是否上報」這個(gè)決定在請求入口服務(wù) (即 HTTP 服務(wù)) 做出,并會(huì )隨著(zhù)跨進(jìn)程調用傳播到下游服務(wù),同時(shí)伴魚(yú)服務(wù)端內部的入口服務(wù)已經(jīng)按照業(yè)務(wù)拆分,因此灰度的過(guò)程就可以按入口服務(wù)進(jìn)行,從流量小的、級別低入口服務(wù)開(kāi)始上線(xiàn)觀(guān)察,再逐漸加入流量大的、級別高的入口服務(wù),最終默認打開(kāi)全量采樣,并在這個(gè)過(guò)程中發(fā)現、解決潛在問(wèn)題。
  資源消耗優(yōu)化
  新版架構所需資源與舊版差別不大:
  在逐步上線(xiàn)到所有入口服務(wù)之前,我們做了比較充分的風(fēng)險評估。開(kāi)啟全量采集后,主要增加了宿主機的網(wǎng)絡(luò ) i/o,在千兆網(wǎng)卡 (約 300MB/s) 支持下,增加后的 i/o 量遠遠未達到瓶頸。實(shí)施過(guò)程中,業(yè)務(wù)團隊也確實(shí)沒(méi)有感知。不過(guò)在灰度上線(xiàn)過(guò)程中,我們也發(fā)現并解決了若干問(wèn)題。
  熱點(diǎn)服務(wù)問(wèn)題
  不同服務(wù)的請求量不同。個(gè)別服務(wù)的上報量過(guò)大會(huì )導致不同 otel-agent 的流量不均衡,在高峰期造成 otel-agent 的 CPU 經(jīng)常超過(guò)預警線(xiàn)。我們通過(guò)增加熱點(diǎn)服務(wù)實(shí)例,減小單個(gè)實(shí)例的請求量的方式,間接地均衡了每個(gè) otel-agent 承載的流量。
  過(guò)濾下推
  在生產(chǎn)環(huán)境中,我們默認維持最近 7 天的 trace 數據。在分析 ES 中索引jaeger-span-* 的過(guò)程中,意料之中地,我們看到了 power law 的存在:
  
  仔細分析可以發(fā)現,50% 以上的 span 都屬于apolloConfigCenter.*。熟悉 apollo 的研發(fā)應該知道,通常 apollo sdk 會(huì )通過(guò)長(cháng)輪詢(xún)的方式從元數據中心拉取配置信息,并緩存到本地,而服務(wù)在應用層獲取配置都是通過(guò)本地緩存獲取。因此實(shí)際上這里的所有apolloConfigCenter.*只是本地訪(fǎng)問(wèn),而不是跨進(jìn)程調用,span 數據價(jià)值比較低,可以忽略。于是我們開(kāi)發(fā)了通過(guò)正則匹配 spanName 過(guò)濾 span 的 processor,并部署到 otel-agent 上,我們稱(chēng)之為過(guò)濾下推。部署上線(xiàn)后,ES 索引體積下降超過(guò) 50%,目前每天索引體積為 40-50 GB;otel-collector 和 otel-agent 的 CPU 消耗也降低了接近 50%。
  制定 SLO
  在伴魚(yú)服務(wù)端內,線(xiàn)上問(wèn)題排查的第一入口通常是 im 消息,報警平臺會(huì )將導致報警的 traceID 以及日志注入到消息中,并提供一個(gè)鏈接頁(yè)面,方便研發(fā)快速查看報警相關(guān)的調用鏈信息及其在整個(gè)調用鏈上每個(gè)服務(wù)打印的日志?;诖宋覀冎贫ㄐ掳嬲{用鏈追蹤系統的SLO:
  名稱(chēng)
  研發(fā)關(guān)心的 trace 數據采集成功率
  SLI 規范
  研發(fā)關(guān)心且被采集的 trace 個(gè)數/研發(fā)關(guān)心的 trace 個(gè)數
  SLI 實(shí)現
  包含 trace 數據的服務(wù)報警信息條數/服務(wù)報警信息條數
  查詢(xún)
  sum(alertmanager_alert_total{trace_exists="true"})/sum(alertmanager_alert_total)
  目標
  99%
  目前我們剛剛在報警平臺中支持此 SLI 的埋點(diǎn)。目前還有個(gè)別服務(wù)尚未升級相關(guān)依賴(lài),因此該指標尚不能反映所有服務(wù)的情況,我們會(huì )繼續推動(dòng)各服務(wù)全面升級,按照以上 SLO 來(lái)要求新版系統。
  總結
  借助開(kāi)源項目,我們得以通過(guò)花費極少的人力,解決當前伴魚(yú)內部調用鏈追蹤應用的穩態(tài)分析及異常檢測需求,同時(shí)也為開(kāi)源項目和社區做出微小的貢獻。調用鏈追蹤是可觀(guān)測性平臺的重要組件,未來(lái)我們將繼續把一些精力放在 telemetry data 的整合上,為研發(fā)提供更全面、一致的服務(wù)觀(guān)測分析體驗。
  介紹
  文章原創(chuàng )來(lái)自于伴魚(yú)技術(shù)團隊的鄭鶴。
  伴魚(yú)少兒英語(yǔ)是目前飛速成長(cháng)的互聯(lián)網(wǎng)在線(xiàn)英語(yǔ)教育品牌之一。我們期望打造更創(chuàng )新、更酷、讓學(xué)英語(yǔ)更有效的新一代互聯(lián)網(wǎng)產(chǎn)品。轉載:著(zhù)作權歸作者所有。商業(yè)轉載請聯(lián)系作者獲得授權,非商業(yè)轉載請注明出處。
  Hi,我是老蔣。這里是中國Opentelemetry官方開(kāi)源社區組織。我們定期分享精彩的Opentelemetry 落地案例,請大家持續關(guān)注
  
  參考 查看全部

  調用鏈追蹤系統在伴魚(yú):Opentelemetry最佳實(shí)踐案例分享
  搭建可靠的鏈路追蹤系統
  在正式介紹前,簡(jiǎn)單交代一下背景:2015 年,在伴魚(yú)服務(wù)端起步之時(shí),技術(shù)團隊就做出統一使用 Go 語(yǔ)言的決定。這個(gè)決定的影響主要體現在:
  早期實(shí)踐對接 Jaeger
  2019 年,公司內部的微服務(wù)數量逐步增加,調用關(guān)系日趨復雜,工程師做性能分析、問(wèn)題排查的難度變大。這時(shí)亟需一套調用鏈追蹤系統幫助我們增強對服務(wù)端全貌的了解。經(jīng)過(guò)調研后,我們決定采用同樣基于 Go 語(yǔ)言搭建的、由 CNCF 孵化的項目Jaeger。當時(shí),服務(wù)的開(kāi)發(fā)和治理都尚未引入 context,不論進(jìn)程內部調用還是跨進(jìn)程調用,都沒(méi)有上下文傳遞。因此早期引入調用鏈追蹤的工作重心就落在了服務(wù)及服務(wù)治理框架的改造,包括:
  部署方面:測試環(huán)境采用 all-in-one,線(xiàn)上環(huán)境采用 direct-to-storage 方案。整個(gè)過(guò)程前后大約耗時(shí)一個(gè)月,我們在 2019 年 Q3 上線(xiàn)了第一版調用鏈追蹤系統。配合廣泛被采用的 prometheus + grafana 以及 ELK,我們在微服務(wù)群的可觀(guān)測性上終于湊齊了調用鏈 (traces)、日志 (logs) 和監控指標 (metrics) 三個(gè)要素。
  下圖是第一版調用鏈追蹤系統的數據上報通路示意圖。服務(wù)運行在容器中,通過(guò) opentracing 的 sdk 埋點(diǎn),Jaeger 的 go-sdk 上報到宿主機上的 Jaeger-agent,后者再將數據進(jìn)一步上報到 Jaeger-collector,最終將調用鏈數據寫(xiě)入 ES,建立索引,即圖中的 Jaeger backends。
  
  遇到的問(wèn)題
  Jaeger 支持三種采樣方式:
  調用鏈通路改造使用場(chǎng)景
  2020 年,我們不斷收到業(yè)務(wù)研發(fā)的反饋:能不能全量采集 trace?
  這促使我們開(kāi)始重新思考如何改進(jìn)調用鏈追蹤系統。我們做了一個(gè)簡(jiǎn)單的容量預估:目前 Jaeger 每天寫(xiě)入 ES 的數據量接近 100GB/天,如果要全量采集 trace 數據,保守假設平均每個(gè) HTTP API 服務(wù)的總 QPS 為 100,那么完整存下全量數據需要 10TB/天;樂(lè )觀(guān)假設 100 名服務(wù)器研發(fā)每人每天查看 1 條 trace,每條 trace 的平均大小為 1KB,則整體信噪比千萬(wàn)分之一??梢钥闯?,這件事情本身的 ROI 很低,考慮到未來(lái)業(yè)務(wù)會(huì )持續增長(cháng),存儲這些數據的價(jià)值也會(huì )繼續降低,因此全量采集的方案被放棄。退一步想:全量采集真的是本質(zhì)需求嗎?實(shí)際上并非如此,我們想要的其實(shí)是「有意思」的 trace 全采,「沒(méi)意思」的 trace 不采。
  根據 理論篇 中介紹的應用場(chǎng)景,實(shí)際上第一版調用鏈追蹤系統只支持了穩態(tài)分析,而業(yè)務(wù)研發(fā)亟需的是異常檢測。要同時(shí)支持這兩種場(chǎng)景,我們必須借助尾部連貫采樣 (tail-based coherent sampling)。相對于頭部連貫采樣在第一個(gè) span 處就做出是否采樣的決定,尾部連貫采樣可以讓我們在獲取 (接近) 完整的 trace 信息后再做出判斷。理想情況下,只要能合理地制定采樣的判斷邏輯,我們的調用鏈追蹤系統就能做到「有意思」的 trace 全采,「沒(méi)意思」的 trace 不采。
  架構設計
  Jaeger 團隊從 2017 年就開(kāi)始討論引入 tail-based sampling 的可能性,但至今未有定論。在一次與 Jaeger 工程師 jpkrohling 的一對一溝通中,對方也證實(shí)了目前 Jaeger 尚沒(méi)有相關(guān)的支持計劃。因此,我們不得不另辟蹊徑。經(jīng)過(guò)一番調研,我們找到了剛剛進(jìn)駐 CNCF SandBox 的OpenTelemetry,它的opentelemetry-collector子項目恰好能支持我們在現有架構上引入尾部連貫采樣。
  OpenTelemetry Collector
  整個(gè) OpenTelemetry 項目目的在于統一市面上可觀(guān)測性數據 (telemetry data) 的標準,同時(shí)提供推動(dòng)這些標準實(shí)施的組件和工具。opentelemetry-collector 就是這個(gè)生態(tài)中的一個(gè)重要組件,它的架構圖如下:
  
  collector 內部有 4 個(gè)核心組件:
  opentelemetry-collector 項目被拆成兩部分:主項目 opentelemetry-collector 和社區貢獻項目 opentelemetry-collector-contrib,前者負責管理核心邏輯、數據結構以及通用的 Receivers、Processors、Exporters、Extensions 實(shí)現,后者則負責接收一些社區貢獻的組件,當然貢獻者主要都來(lái)自于可觀(guān)測性 SaaS 解決方案供應商,如 DataDog、Splunk、LightStep 以及一些公有云廠(chǎng)商。opentelemtry-collector 項目的插件化管理方式,使得定制化開(kāi)發(fā) Receiver、Processor、Exporter 的成本很低,我們在做概念驗證時(shí),基本可以在一兩個(gè)小時(shí)內開(kāi)發(fā)并測試完畢一個(gè)組件。除此之外,opentelemetry-collector-contrib 還提供了開(kāi)箱即用的tailsamplingprocessor。
  由于 opentelemetry-collector 是 OpenTelemetry 團隊推動(dòng)標準實(shí)施的重要組件,且 OpenTelemetry 本身并沒(méi)有提供獨立的數據存儲、索引實(shí)現的計劃,因此它在與市面上流行的調用鏈追蹤框架,如 Zipkin、Jaeger、OpenCensus,的兼容性上下了很大功夫。通過(guò) Receivers 和 Exporters 的使用,我們可以用它替換 jaeger-agent,也可以放在 jaeger-agent 與 jaeger-collector 之間,必要時(shí)還可以在 jaeger-agent 和 jaeger-collector 之間部署多層 collectors。除此之外,如果有一天想換掉 jaeger-backend,比如新發(fā)布的 Grafana Tempo,我們也能很輕松的完成,并且利用多個(gè) Pipelines 或一個(gè) Pipeline 多個(gè) Exporters 灰度上線(xiàn),逐步替換。
  上報通路
  基于以上的調研和現有的架構,我們設計了第二版調用鏈追蹤的架構,如下圖所示:
  
  用一組 opentelemetry-collector 替換 jaeger-agent,即圖中的 otel-agent;同時(shí)在 otel-agent 與 jaeger-collector 之間增加另一組 opentelemetry-collector,即圖中的 otel-collector。otel-agent 收集宿主機上不同服務(wù)上報的 trace 數據,打包批量發(fā)送給 otel-collector,后者負責做尾部連貫采樣,將「有意思」的 trace 繼續輸出到原始架構中的 jaeger-collector,后者負責將數據投入 ElasticSearch 中,建立索引。
  這里還有一個(gè)問(wèn)題需要解決:整個(gè)架構做到高可用,勢必要部署多個(gè) otel-collector 實(shí)例,如果使用簡(jiǎn)單的負載均衡策略,不同 otel-agents、以及單個(gè) otel-agent 不同時(shí)刻上報的數據,可能被隨機上報到某個(gè) otel-collector 實(shí)例,這就意味著(zhù),同一個(gè) trace 的不同 spans 無(wú)法集中到同一個(gè) otel-collector 實(shí)例上,既會(huì )導致同一個(gè) trace 的不同 spans 的決定不一致,即不是連貫采樣;也會(huì )導致尾部采樣時(shí)提供判斷的數據不全。解決方案很簡(jiǎn)單:讓 otel-agent 按照 traceID 做負載均衡。
  在調研階段我們正好看到 opentelemetry-collector 社區也有此支持計劃,并且前面提到的工程師 jpkrohling 正在通過(guò)增加loadbalancingexporter解決它,雖然直接使用 bleeding edge 的版本有一定的風(fēng)險,我們還是決定嘗試。在概念驗證階段,我們也的確發(fā)現了新功能的若干問(wèn)題,但通過(guò)反饋的方式一一解決,最終獲得了可以按預期執行尾部連貫采樣的調用鏈追蹤系統。
  采樣規則
  尾部連貫采樣的數據通路已經(jīng)準備就緒,下一步就是確定和實(shí)施采樣規則。
  「有意思」的調用鏈
  什么是「有意思」的調用鏈?研發(fā)在分析、排障過(guò)程中想查詢(xún)的任何調用鏈就是「有意思」的調用鏈。但落實(shí)到代碼的必須是確定性的規則,根據日常排障經(jīng)驗,我們先確定了以下三種情形:
  滿(mǎn)足任意條件,就認為這個(gè)調用鏈「有意思」。在伴魚(yú),只要服務(wù)打印了 ERROR 級別的日志就會(huì )觸發(fā)報警,研發(fā)人員就會(huì )收到 im 消息或電話(huà)報警,如果能保證觸發(fā)報警的調用鏈數據必采,研發(fā)人員的排障體驗就會(huì )有很大的提升;我們的 DBA 團隊認為超過(guò) 200ms 的查詢(xún)請求都被判定為慢查詢(xún),如果能保證這些請求的調用鏈必采,就能大大方便研發(fā)排查導致慢查詢(xún)的請求;對于在線(xiàn)服務(wù)來(lái)說(shuō),時(shí)延過(guò)高會(huì )令用戶(hù)體驗下降,但具體高到什么程度會(huì )引發(fā)明顯的體驗下降我們暫時(shí)沒(méi)有數據支撐,因此先配置為 1s,支持隨時(shí)修改閾值。
  當然,以上條件并不絕對,我們可以在之后的實(shí)踐根據反饋調整、新增規則,如單個(gè)請求引起的數據庫、緩存查詢(xún)次數超過(guò)某閾值等。
  采樣流水線(xiàn)
  在第二版系統中,我們期望同時(shí)支持穩態(tài)分析與異常檢測,因此采樣過(guò)程既要按概率或限流方式采集一部分 trace,也需要按上文擬定的「有意思」 規則采集令一部分 trace。截止到本文撰寫(xiě)前,tailsamplingprocessor支持 4 種策略:
  「按概率或限流采集一部分 trace」可以利用rate_limiting實(shí)現嗎?rate_limiting只能按照每秒通過(guò)的 spans 個(gè)數限流,但 spans 數量在高峰期、低峰期、業(yè)務(wù)所處階段都不一樣,每個(gè) trace 的平均 spans 數量也會(huì )隨著(zhù)微服務(wù)群規模以及依賴(lài)關(guān)系發(fā)生變化,因此設置 spans_per_second 將讓我們很難對這個(gè)參數的最終效果合理評估,因此直接使用rate_limiting的方案被否決。
  「按規則采集另一部分 trace」可以直接使用numeric_attribute和string_attribute實(shí)現嗎?span 中還存在布爾 (bool) 類(lèi)型的 tag,以「在調用鏈上如果打印了 ERROR 級別日志」為例,按照規范我們會(huì )記錄span.SetTag("error" , true),但 tailsamplingprocessor 并未支持bool_attribute;此外,未來(lái)我們可能會(huì )有更復雜的組合條件,這時(shí)僅靠numeric_attribute和string_attribute也無(wú)法實(shí)現。
  經(jīng)過(guò)再三分析,我們最終決定利用 Processors 的鏈式結構,組合多個(gè) Processor 完成采樣,流水線(xiàn)如下圖所示:
  
  其中probattr負責在 trace 級別按概率抽樣,anomaly 負責分析每個(gè) trace 是否符合「有意思」的規則,如果命中二者之一,trace 就會(huì )被打上標記,即sampling.priority。最后在tailsamplingprocessor上配置一條規則即可,如下所示:
  tail_sampling:<br />???policies:<br />?????[<br />???????{<br />?????????name:?sample_with_high_priority,<br />?????????type:?numeric_attribute,<br />?????????numeric_attribute:?{?key:?"sampling.priority",?min_value:?1,?max_value:?1?}<br />???????}<br />?????]
  這里sampling.priority是整數類(lèi)型,當前取值只有 0 和 1。按上面的配置,所以sampling.priority = 1的trace 都會(huì )被采集。后期可以增加更多的采集優(yōu)先級,在必要的時(shí)候可以多采樣 (upsampling) 或降采樣 (downsampling)。
  部署實(shí)施
  采樣規則確立后,整個(gè)解決方案就已跑通,下一步就是進(jìn)入部署實(shí)施階段。
  上線(xiàn)準備基礎庫改造
  動(dòng)態(tài)更新 Tracer在第一版系統中,每個(gè)進(jìn)程啟動(dòng)時(shí)會(huì )從 apollo 上獲取采樣配置,傳遞給 Jaeger sdk,后者利用配置初始化 GlobalTracer。GlobalTracer 會(huì )在 trace 的第一個(gè) span 出現時(shí),決定是否采集,并把這個(gè)決定傳遞下去,即頭部連貫采樣。在實(shí)施新架構時(shí),我們需要 Jaeger sdk 將所有 trace 數據盡數上報。為了讓這個(gè)過(guò)程更加平滑,我們對 Jaeger sdk 配置做出兩方面改造:
  支持對每個(gè)服務(wù)下發(fā)不同的采樣配置,方便灰度發(fā)布 支持動(dòng)態(tài)更新采樣配置,使采樣策略配置不依賴(lài)發(fā)布
  日志庫改造為了保證打印過(guò) ERROR 級別日志的調用鏈必采,我們也在通用日志庫的相應位置上給 span 打上 error 標簽。
  監控看板配置
  opentelemetry-collector 內部利用 OpenCensus sdk 埋了很多有用的監控指標,并按照 Open Metrics 規范暴露數據。因為指標數量并不多,我們將大多數指標都配置了到 Grafana 看板中,包括:
  xxx_receiver_accepted/refused_spans這里的 xxx 指代任意一個(gè) pipeline 中使用的 receiver。實(shí)際上這里有兩個(gè)具體指標:receiver 接收的 spans 數量和 receiver 拒絕的 spans 數量。二者可以與其它指標結合,分析系統在當前狀況下的入口流量瓶頸。
  xxx_exporter_send(failed)_spans這里的 xxx 指代任意一個(gè) pipeline 中使用的 exporter。實(shí)際上這里有兩個(gè)具體指標:exporter 發(fā)送成功的 spans 數量和 exporter 發(fā)送失敗的 spans 數量。二者可以與其它指標結合,分析系統在當前狀況下的出口流量瓶頸。
  otelcol_processor_tail_sampling_sampling_trace_dropped_too_early要介紹上面這個(gè)指標,需要簡(jiǎn)單了解tailsamplingprocessor的工作原理。在分布式環(huán)境中,tailsamplingprocessor永遠無(wú)法確定一個(gè) trace 的所有 spans 在當前時(shí)刻是否收集完畢,因此需要設置一個(gè)超時(shí)時(shí)間,即 這里 的decision_wait,下面假設decision_wait = 5s。Trace Data 進(jìn)入 processor 后,會(huì )被分別放入兩個(gè)數據結構:
  
  一個(gè)固定大小的隊列和一個(gè)哈希表,二者合起來(lái)實(shí)現 trace data 的 LRU cache。同時(shí) processor 會(huì )將所有進(jìn)入到其中的 traces 按照每秒一個(gè) batch 組織起來(lái),內部一共維持 5 個(gè) batch (decision_wait)。每隔一秒鐘,將最老的 batch 取出來(lái),對其中的 traces 分別判斷是否符合采樣規則,符合則將其傳遞給后續的 processors:
  
  如果在做采樣決策時(shí),發(fā)現相應的 trace 已經(jīng)被 LRU cache 清出,則認為「trace dropped too early」,后者意味著(zhù)tailsamplingprocessor已經(jīng)超負荷。理論上這個(gè)指標如果不等于 0,尾部連貫采樣功能就處于異常狀態(tài)。
  灰度方案
  上文提到過(guò),實(shí)施改造需要讓 Jaeger sdk 全量上報 trace。由于「是否上報」這個(gè)決定在請求入口服務(wù) (即 HTTP 服務(wù)) 做出,并會(huì )隨著(zhù)跨進(jìn)程調用傳播到下游服務(wù),同時(shí)伴魚(yú)服務(wù)端內部的入口服務(wù)已經(jīng)按照業(yè)務(wù)拆分,因此灰度的過(guò)程就可以按入口服務(wù)進(jìn)行,從流量小的、級別低入口服務(wù)開(kāi)始上線(xiàn)觀(guān)察,再逐漸加入流量大的、級別高的入口服務(wù),最終默認打開(kāi)全量采樣,并在這個(gè)過(guò)程中發(fā)現、解決潛在問(wèn)題。
  資源消耗優(yōu)化
  新版架構所需資源與舊版差別不大:
  在逐步上線(xiàn)到所有入口服務(wù)之前,我們做了比較充分的風(fēng)險評估。開(kāi)啟全量采集后,主要增加了宿主機的網(wǎng)絡(luò ) i/o,在千兆網(wǎng)卡 (約 300MB/s) 支持下,增加后的 i/o 量遠遠未達到瓶頸。實(shí)施過(guò)程中,業(yè)務(wù)團隊也確實(shí)沒(méi)有感知。不過(guò)在灰度上線(xiàn)過(guò)程中,我們也發(fā)現并解決了若干問(wèn)題。
  熱點(diǎn)服務(wù)問(wèn)題
  不同服務(wù)的請求量不同。個(gè)別服務(wù)的上報量過(guò)大會(huì )導致不同 otel-agent 的流量不均衡,在高峰期造成 otel-agent 的 CPU 經(jīng)常超過(guò)預警線(xiàn)。我們通過(guò)增加熱點(diǎn)服務(wù)實(shí)例,減小單個(gè)實(shí)例的請求量的方式,間接地均衡了每個(gè) otel-agent 承載的流量。
  過(guò)濾下推
  在生產(chǎn)環(huán)境中,我們默認維持最近 7 天的 trace 數據。在分析 ES 中索引jaeger-span-* 的過(guò)程中,意料之中地,我們看到了 power law 的存在:
  
  仔細分析可以發(fā)現,50% 以上的 span 都屬于apolloConfigCenter.*。熟悉 apollo 的研發(fā)應該知道,通常 apollo sdk 會(huì )通過(guò)長(cháng)輪詢(xún)的方式從元數據中心拉取配置信息,并緩存到本地,而服務(wù)在應用層獲取配置都是通過(guò)本地緩存獲取。因此實(shí)際上這里的所有apolloConfigCenter.*只是本地訪(fǎng)問(wèn),而不是跨進(jìn)程調用,span 數據價(jià)值比較低,可以忽略。于是我們開(kāi)發(fā)了通過(guò)正則匹配 spanName 過(guò)濾 span 的 processor,并部署到 otel-agent 上,我們稱(chēng)之為過(guò)濾下推。部署上線(xiàn)后,ES 索引體積下降超過(guò) 50%,目前每天索引體積為 40-50 GB;otel-collector 和 otel-agent 的 CPU 消耗也降低了接近 50%。
  制定 SLO
  在伴魚(yú)服務(wù)端內,線(xiàn)上問(wèn)題排查的第一入口通常是 im 消息,報警平臺會(huì )將導致報警的 traceID 以及日志注入到消息中,并提供一個(gè)鏈接頁(yè)面,方便研發(fā)快速查看報警相關(guān)的調用鏈信息及其在整個(gè)調用鏈上每個(gè)服務(wù)打印的日志?;诖宋覀冎贫ㄐ掳嬲{用鏈追蹤系統的SLO:
  名稱(chēng)
  研發(fā)關(guān)心的 trace 數據采集成功率
  SLI 規范
  研發(fā)關(guān)心且被采集的 trace 個(gè)數/研發(fā)關(guān)心的 trace 個(gè)數
  SLI 實(shí)現
  包含 trace 數據的服務(wù)報警信息條數/服務(wù)報警信息條數
  查詢(xún)
  sum(alertmanager_alert_total{trace_exists="true"})/sum(alertmanager_alert_total)
  目標
  99%
  目前我們剛剛在報警平臺中支持此 SLI 的埋點(diǎn)。目前還有個(gè)別服務(wù)尚未升級相關(guān)依賴(lài),因此該指標尚不能反映所有服務(wù)的情況,我們會(huì )繼續推動(dòng)各服務(wù)全面升級,按照以上 SLO 來(lái)要求新版系統。
  總結
  借助開(kāi)源項目,我們得以通過(guò)花費極少的人力,解決當前伴魚(yú)內部調用鏈追蹤應用的穩態(tài)分析及異常檢測需求,同時(shí)也為開(kāi)源項目和社區做出微小的貢獻。調用鏈追蹤是可觀(guān)測性平臺的重要組件,未來(lái)我們將繼續把一些精力放在 telemetry data 的整合上,為研發(fā)提供更全面、一致的服務(wù)觀(guān)測分析體驗。
  介紹
  文章原創(chuàng )來(lái)自于伴魚(yú)技術(shù)團隊的鄭鶴。
  伴魚(yú)少兒英語(yǔ)是目前飛速成長(cháng)的互聯(lián)網(wǎng)在線(xiàn)英語(yǔ)教育品牌之一。我們期望打造更創(chuàng )新、更酷、讓學(xué)英語(yǔ)更有效的新一代互聯(lián)網(wǎng)產(chǎn)品。轉載:著(zhù)作權歸作者所有。商業(yè)轉載請聯(lián)系作者獲得授權,非商業(yè)轉載請注明出處。
  Hi,我是老蔣。這里是中國Opentelemetry官方開(kāi)源社區組織。我們定期分享精彩的Opentelemetry 落地案例,請大家持續關(guān)注
  
  參考

文章采集調用(中國的股票市場(chǎng)上盈利,每周都有單個(gè)股票盈利2)

采集交流 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 146 次瀏覽 ? 2022-04-18 07:10 ? 來(lái)自相關(guān)話(huà)題

  文章采集調用(中國的股票市場(chǎng)上盈利,每周都有單個(gè)股票盈利2)
  目標:在中國股市盈利,單只股票每周盈利2%,月總盈利超過(guò)2%
  計劃實(shí)現:Pycharm + Anaconda3 + Python3 + Django + AKShare + MongoDB
  當前實(shí)現:Pycharm + Anaconda3 + Python3 + Flask + AKShare
  未來(lái)可能會(huì )用到:MongoDB、SQLAlchemy、baostock、Tushare
  機器學(xué)習將在未來(lái)的實(shí)踐中逐步使用。
  實(shí)現方法
  上一篇文章寫(xiě)過(guò)采集的方法。本文文章收錄完整代碼和調用代碼。
  使用后臺執行的方法。
  gupiao.py如下:
  
import akshare as ak
import threading
import datetime
import os
from threading import Thread
def get_start():
start_stock_daily()
# 這里就是核心了,調用這部分就會(huì )自動(dòng)下載 深圳A(yíng)股 的所有股票的歷史記錄
def start_stock_daily(indicator="A股列表", folder="sz_a", prefix="sz"):
file_path = "D:/work/data/" + folder + "/"
file_path_name = get_sz_a(file_path, indicator)
print(file_path_name)
num = 0
with open(file_path_name, "r", encoding=&#39;UTF-8&#39;) as stock_lines:
for stock_line in stock_lines.readlines():
num = num + 1
if num == 1:
continue
stock_line_arr = stock_line.split("|")
symbol = prefix + stock_line_arr[5]
print("股票信息=" + symbol + "||" + stock_line_arr[6])
stock_csv = get_stock_daily(file_path, symbol)
print("stock_csv=" + stock_csv)
# 獲得深圳主板A股列表,每天獲取一次不重復獲取
# file_path 需要全路徑,以 | 進(jìn)行間隔
# indicator 可選參數 "A股列表", "B股列表", "AB股列表", "上市公司列表", "主板", "中小企業(yè)板", "創(chuàng )業(yè)板"
def get_sz_a(file_path, indicator="A股列表"):
today = datetime.datetime.today()
file_name = "sz_a_" + today.strftime(&#39;%Y%m%d&#39;) + ".csv"
if not os.path.exists(file_path): # 如果路徑不存在則創(chuàng )建
os.makedirs(file_path)
if os.path.exists(file_path + file_name):
print("今日已經(jīng)獲取無(wú)需再次獲取," + today.strftime(&#39;%Y%m%d&#39;))
return file_path + file_name
stock_info_sz_df = ak.stock_info_sz_name_code(indicator=indicator)
stock_info_sz_df.to_csv(file_path + file_name, sep="|")
print(&#39;獲取深圳主板A股列表并存儲為CSV!&#39; + today.strftime(&#39;%Y%m%d&#39;))
return file_path + file_name
# 根據股票代碼獲取股票歷史數據
# symbol 股票代碼 需要前綴 sh 上海 sz 深圳,例如:sz300846
def get_stock_daily(file_path, symbol):
stock_zh_a_daily_hfq_df = ak.stock_zh_a_daily(symbol=symbol) # 返回不復權的數據
file_name = symbol + &#39;.csv&#39;
stock_zh_a_daily_hfq_df.to_csv(file_path + file_name)
return file_path + file_name
  調用下載的部分,注意我隨便寫(xiě)的名字,請根據情況修改,app.py如下:
  from flask import Flask
import akshare as ak
import gupiao
import datetime
import os
from concurrent.futures import ThreadPoolExecutor
import time
executor = ThreadPoolExecutor(2)
app = Flask(__name__)
@app.route(&#39;/test_thread&#39;)
def test_thread():
executor.submit(gupiao.get_start)
return "thread is running at background !!!"
if __name__ == &#39;__main__&#39;:
app.run()
  使用Flask框架,生成一個(gè)項目,然后在app.py中創(chuàng )建一個(gè)gupiao.py,并運行該項目。
  在瀏覽器中訪(fǎng)問(wèn):5000/test_thread
  可以在后臺看到圖片,整個(gè)深圳A(yíng)股的下載時(shí)間大約是2小時(shí)到3小時(shí)。
  
  歷史股票數據
  如圖下載到本地
  
  歷史股票數據
  爬取數據部分完成,接下來(lái)就是過(guò)濾了。 查看全部

  文章采集調用(中國的股票市場(chǎng)上盈利,每周都有單個(gè)股票盈利2)
  目標:在中國股市盈利,單只股票每周盈利2%,月總盈利超過(guò)2%
  計劃實(shí)現:Pycharm + Anaconda3 + Python3 + Django + AKShare + MongoDB
  當前實(shí)現:Pycharm + Anaconda3 + Python3 + Flask + AKShare
  未來(lái)可能會(huì )用到:MongoDB、SQLAlchemy、baostock、Tushare
  機器學(xué)習將在未來(lái)的實(shí)踐中逐步使用。
  實(shí)現方法
  上一篇文章寫(xiě)過(guò)采集的方法。本文文章收錄完整代碼和調用代碼。
  使用后臺執行的方法。
  gupiao.py如下:
  
import akshare as ak
import threading
import datetime
import os
from threading import Thread
def get_start():
start_stock_daily()
# 這里就是核心了,調用這部分就會(huì )自動(dòng)下載 深圳A(yíng)股 的所有股票的歷史記錄
def start_stock_daily(indicator="A股列表", folder="sz_a", prefix="sz"):
file_path = "D:/work/data/" + folder + "/"
file_path_name = get_sz_a(file_path, indicator)
print(file_path_name)
num = 0
with open(file_path_name, "r", encoding=&#39;UTF-8&#39;) as stock_lines:
for stock_line in stock_lines.readlines():
num = num + 1
if num == 1:
continue
stock_line_arr = stock_line.split("|")
symbol = prefix + stock_line_arr[5]
print("股票信息=" + symbol + "||" + stock_line_arr[6])
stock_csv = get_stock_daily(file_path, symbol)
print("stock_csv=" + stock_csv)
# 獲得深圳主板A股列表,每天獲取一次不重復獲取
# file_path 需要全路徑,以 | 進(jìn)行間隔
# indicator 可選參數 "A股列表", "B股列表", "AB股列表", "上市公司列表", "主板", "中小企業(yè)板", "創(chuàng )業(yè)板"
def get_sz_a(file_path, indicator="A股列表"):
today = datetime.datetime.today()
file_name = "sz_a_" + today.strftime(&#39;%Y%m%d&#39;) + ".csv"
if not os.path.exists(file_path): # 如果路徑不存在則創(chuàng )建
os.makedirs(file_path)
if os.path.exists(file_path + file_name):
print("今日已經(jīng)獲取無(wú)需再次獲取," + today.strftime(&#39;%Y%m%d&#39;))
return file_path + file_name
stock_info_sz_df = ak.stock_info_sz_name_code(indicator=indicator)
stock_info_sz_df.to_csv(file_path + file_name, sep="|")
print(&#39;獲取深圳主板A股列表并存儲為CSV!&#39; + today.strftime(&#39;%Y%m%d&#39;))
return file_path + file_name
# 根據股票代碼獲取股票歷史數據
# symbol 股票代碼 需要前綴 sh 上海 sz 深圳,例如:sz300846
def get_stock_daily(file_path, symbol):
stock_zh_a_daily_hfq_df = ak.stock_zh_a_daily(symbol=symbol) # 返回不復權的數據
file_name = symbol + &#39;.csv&#39;
stock_zh_a_daily_hfq_df.to_csv(file_path + file_name)
return file_path + file_name
  調用下載的部分,注意我隨便寫(xiě)的名字,請根據情況修改,app.py如下:
  from flask import Flask
import akshare as ak
import gupiao
import datetime
import os
from concurrent.futures import ThreadPoolExecutor
import time
executor = ThreadPoolExecutor(2)
app = Flask(__name__)
@app.route(&#39;/test_thread&#39;)
def test_thread():
executor.submit(gupiao.get_start)
return "thread is running at background !!!"
if __name__ == &#39;__main__&#39;:
app.run()
  使用Flask框架,生成一個(gè)項目,然后在app.py中創(chuàng )建一個(gè)gupiao.py,并運行該項目。
  在瀏覽器中訪(fǎng)問(wèn):5000/test_thread
  可以在后臺看到圖片,整個(gè)深圳A(yíng)股的下載時(shí)間大約是2小時(shí)到3小時(shí)。
  
  歷史股票數據
  如圖下載到本地
  
  歷史股票數據
  爬取數據部分完成,接下來(lái)就是過(guò)濾了。

文章采集調用(如何使用采集功能去采集一個(gè)圖片類(lèi)的網(wǎng)站(組圖))

采集交流 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 188 次瀏覽 ? 2022-04-17 17:12 ? 來(lái)自相關(guān)話(huà)題

  文章采集調用(如何使用采集功能去采集一個(gè)圖片類(lèi)的網(wǎng)站(組圖))
  前言:本文章主要介紹如何使用采集函數來(lái)采集一個(gè)圖片類(lèi)網(wǎng)站。本次選擇的目標站點(diǎn)為:戰酷網(wǎng)名作鑒賞欄目,網(wǎng)址為:. 本文將介紹如何處理收錄 采集 分頁(yè)的頁(yè)面以及如何使用簡(jiǎn)單的過(guò)濾規則。本文分為三部分:第一部分主要介紹如何進(jìn)入采集界面以及添加新采集節點(diǎn)的第一步:設置基本信息和URL索引頁(yè)面規則;第二部分,主要是引入新的采集節點(diǎn)的第二步:設置字段獲取規則;第三節主要介紹采集如何指定節點(diǎn)以及如何導出采集內容。
  進(jìn)入下面的第一部分。
  1.1進(jìn)入采集節點(diǎn)管理界面
  如圖1),在后臺管理界面主菜單點(diǎn)擊“采集”,再點(diǎn)擊“采集節點(diǎn)管理”進(jìn)入采集節點(diǎn)管理界面,如圖(圖2).
  
  圖 1 - 后臺管理界面
  
  圖2-采集節點(diǎn)管理界面
  1.2. 添加新節點(diǎn)
  在采集節點(diǎn)管理界面,點(diǎn)擊左下角“添加新節點(diǎn)”或右上角“添加新節點(diǎn)”(如圖2),可以輸入“選擇內容模型”界面,如(如圖3),
  
  圖 3 - 選擇內容模型界面
  在“選擇內容模型”界面的下拉列表框中,有“普通文章”和“圖片采集”可供選擇。
  根據頁(yè)面類(lèi)型為采集,選擇對應的內容模型。本文選擇“圖片采集”,點(diǎn)擊確定,即可進(jìn)入“添加采集節點(diǎn):第一步設置基本信息和URL索引頁(yè)面規則”界面,如圖(圖4)@ &gt; ,
  
  圖4 - 添加采集節點(diǎn):第一步設置基本信息和URL索引頁(yè)面規則
  1.2.1 設置節點(diǎn)基本信息
  
  圖 5 - 節點(diǎn)基本信息
  如圖(圖5),這里只是獲取“目標頁(yè)面代碼”的方法,其他設置請參考前面的文章。具體操作步驟:
  (a) 打開(kāi) 采集: 所針對的目標頁(yè)面;
  (b) 右擊選擇“查看源文件”找到“charset”,如圖(圖6),
  
  圖 6 - 查看源文件
  等號后面的代碼就是需要填寫(xiě)的“編碼格式”,這里是“utf-8”。
  填寫(xiě)后,如圖(圖7),
  
  圖 7 - 設置后節點(diǎn)的基本信息
  檢查后,進(jìn)入下一步。
  1.2.2 設置列表URL獲取規則
  
  圖 8 - 列出 URL 獲取規則
  如(圖8),這里是設置采集的文章列表頁(yè)的匹配規則。具體步驟:
  (a) 首先,回到打開(kāi)的列表頁(yè)面,找到瀏覽器的URL地址欄中顯示的URL和頁(yè)面的分頁(yè)符部分。如(圖9)和(圖10))所示,
  
  圖 9 - 瀏覽器的 URL 地址欄
  
  圖 10 - 頁(yè)面提要
  (b) 點(diǎn)擊“2”打開(kāi)文章列表頁(yè)面的第二頁(yè),再次找到瀏覽器的URL地址欄顯示的URL和頁(yè)面的換頁(yè)部分,如圖(圖12)和(如圖13),
  
  圖 11 - 第二頁(yè)的 URL
  
  圖 12 - 第二頁(yè)上的換頁(yè)
  (c) 在打開(kāi)的列表頁(yè)第二頁(yè),點(diǎn)擊(1)返回列表頁(yè)第一頁(yè),頁(yè)面換頁(yè)部分同上圖10,只是瀏覽器URL地址欄顯示的URL與上圖9不同,如圖(圖13),
  
  圖 13 - 第一個(gè)頁(yè)面的 URL
  (d) 由(b)和(c)可知,這里采集的列表頁(yè)的URL遵循如下規則:
  !0!0!200!(*)!1!0!0/. 為了安全起見(jiàn),請為自己測試更多列表頁(yè)面。規則確定后,在“匹配網(wǎng)址”中,填寫(xiě)列表頁(yè)后面的規則。
  (e) 最后,根據需要指定采集的頁(yè)碼或常規數,并設置其遞增規則。
  至此,“List URL獲取規則”部分就設置好了。最終結果,如圖(圖14)@>,
  
  圖 14 - 設置后的 URL 獲取規則列表
  確認無(wú)誤后,進(jìn)行下一步。
  1.2.3設置文章網(wǎng)址匹配規則
  
  圖 15 - 文章 URL 匹配規則
  下面是設置采集列表頁(yè)的匹配規則。
  具體步驟:
  
(a)對于“區域開(kāi)始的HTML”,可以在已打開(kāi)的列表首頁(yè),單擊右鍵后選擇“查看源文件”查找出第一篇文章的標題“高清壁紙”來(lái)獲得,如(圖16)所示,
  
  圖 16 - 查看源文件中第一個(gè) 文章 的標題
  通過(guò)觀(guān)察不難看出,“”是整個(gè)列表的結尾,后面的“”是頁(yè)面的分頁(yè)符。所以,在“HTML 結尾區域”中,應該用“”填充,意思是到第一個(gè)結尾。
  (c) 觀(guān)察圖16和圖17中文章的標題部分,可以發(fā)現標題的鏈接地址收錄“=.html”。因此,在“必須收錄”中,填寫(xiě)“=.html”。
  至此,“文章URL匹配規則”就設置好了。填寫(xiě)后,如圖(圖18),
  
  圖 18 - 文章 設置后的 URL 匹配規則
  通過(guò)以上三個(gè)小節,已經(jīng)設置了添加采集節點(diǎn)的第一步。設置后的最終結果,如圖(圖19),
  
  圖19 - 設置后新增采集節點(diǎn):第一步設置基本信息和URL索引頁(yè)面規則
  全部完成并勾選后,點(diǎn)擊“保存信息并進(jìn)入下一步”。如果前面設置正確,點(diǎn)擊后會(huì )進(jìn)入“添加采集節點(diǎn):測試URL索引頁(yè)面規則設置的基本信息和URL獲取規則測試”頁(yè)面,看到對應的文章列表地址. 如圖(圖20),
  
  圖 20 - URL 獲取規則測試
  確認無(wú)誤后,點(diǎn)擊“保存信息并進(jìn)入下一步”。否則,單擊“返回上一步進(jìn)行更改”。
  到這里,第一節就結束了。進(jìn)入下面的第二部分。. . 查看全部

  文章采集調用(如何使用采集功能去采集一個(gè)圖片類(lèi)的網(wǎng)站(組圖))
  前言:本文章主要介紹如何使用采集函數來(lái)采集一個(gè)圖片類(lèi)網(wǎng)站。本次選擇的目標站點(diǎn)為:戰酷網(wǎng)名作鑒賞欄目,網(wǎng)址為:. 本文將介紹如何處理收錄 采集 分頁(yè)的頁(yè)面以及如何使用簡(jiǎn)單的過(guò)濾規則。本文分為三部分:第一部分主要介紹如何進(jìn)入采集界面以及添加新采集節點(diǎn)的第一步:設置基本信息和URL索引頁(yè)面規則;第二部分,主要是引入新的采集節點(diǎn)的第二步:設置字段獲取規則;第三節主要介紹采集如何指定節點(diǎn)以及如何導出采集內容。
  進(jìn)入下面的第一部分。
  1.1進(jìn)入采集節點(diǎn)管理界面
  如圖1),在后臺管理界面主菜單點(diǎn)擊“采集”,再點(diǎn)擊“采集節點(diǎn)管理”進(jìn)入采集節點(diǎn)管理界面,如圖(圖2).
  
  圖 1 - 后臺管理界面
  
  圖2-采集節點(diǎn)管理界面
  1.2. 添加新節點(diǎn)
  在采集節點(diǎn)管理界面,點(diǎn)擊左下角“添加新節點(diǎn)”或右上角“添加新節點(diǎn)”(如圖2),可以輸入“選擇內容模型”界面,如(如圖3),
  
  圖 3 - 選擇內容模型界面
  在“選擇內容模型”界面的下拉列表框中,有“普通文章”和“圖片采集”可供選擇。
  根據頁(yè)面類(lèi)型為采集,選擇對應的內容模型。本文選擇“圖片采集”,點(diǎn)擊確定,即可進(jìn)入“添加采集節點(diǎn):第一步設置基本信息和URL索引頁(yè)面規則”界面,如圖(圖4)@ &gt; ,
  
  圖4 - 添加采集節點(diǎn):第一步設置基本信息和URL索引頁(yè)面規則
  1.2.1 設置節點(diǎn)基本信息
  
  圖 5 - 節點(diǎn)基本信息
  如圖(圖5),這里只是獲取“目標頁(yè)面代碼”的方法,其他設置請參考前面的文章。具體操作步驟:
  (a) 打開(kāi) 采集: 所針對的目標頁(yè)面;
  (b) 右擊選擇“查看源文件”找到“charset”,如圖(圖6),
  
  圖 6 - 查看源文件
  等號后面的代碼就是需要填寫(xiě)的“編碼格式”,這里是“utf-8”。
  填寫(xiě)后,如圖(圖7),
  
  圖 7 - 設置后節點(diǎn)的基本信息
  檢查后,進(jìn)入下一步。
  1.2.2 設置列表URL獲取規則
  
  圖 8 - 列出 URL 獲取規則
  如(圖8),這里是設置采集的文章列表頁(yè)的匹配規則。具體步驟:
  (a) 首先,回到打開(kāi)的列表頁(yè)面,找到瀏覽器的URL地址欄中顯示的URL和頁(yè)面的分頁(yè)符部分。如(圖9)和(圖10))所示,
  
  圖 9 - 瀏覽器的 URL 地址欄
  
  圖 10 - 頁(yè)面提要
  (b) 點(diǎn)擊“2”打開(kāi)文章列表頁(yè)面的第二頁(yè),再次找到瀏覽器的URL地址欄顯示的URL和頁(yè)面的換頁(yè)部分,如圖(圖12)和(如圖13),
  
  圖 11 - 第二頁(yè)的 URL
  
  圖 12 - 第二頁(yè)上的換頁(yè)
  (c) 在打開(kāi)的列表頁(yè)第二頁(yè),點(diǎn)擊(1)返回列表頁(yè)第一頁(yè),頁(yè)面換頁(yè)部分同上圖10,只是瀏覽器URL地址欄顯示的URL與上圖9不同,如圖(圖13),
  
  圖 13 - 第一個(gè)頁(yè)面的 URL
  (d) 由(b)和(c)可知,這里采集的列表頁(yè)的URL遵循如下規則:
  !0!0!200!(*)!1!0!0/. 為了安全起見(jiàn),請為自己測試更多列表頁(yè)面。規則確定后,在“匹配網(wǎng)址”中,填寫(xiě)列表頁(yè)后面的規則。
  (e) 最后,根據需要指定采集的頁(yè)碼或常規數,并設置其遞增規則。
  至此,“List URL獲取規則”部分就設置好了。最終結果,如圖(圖14)@>,
  
  圖 14 - 設置后的 URL 獲取規則列表
  確認無(wú)誤后,進(jìn)行下一步。
  1.2.3設置文章網(wǎng)址匹配規則
  
  圖 15 - 文章 URL 匹配規則
  下面是設置采集列表頁(yè)的匹配規則。
  具體步驟:
  
(a)對于“區域開(kāi)始的HTML”,可以在已打開(kāi)的列表首頁(yè),單擊右鍵后選擇“查看源文件”查找出第一篇文章的標題“高清壁紙”來(lái)獲得,如(圖16)所示,
  
  圖 16 - 查看源文件中第一個(gè) 文章 的標題
  通過(guò)觀(guān)察不難看出,“”是整個(gè)列表的結尾,后面的“”是頁(yè)面的分頁(yè)符。所以,在“HTML 結尾區域”中,應該用“”填充,意思是到第一個(gè)結尾。
  (c) 觀(guān)察圖16和圖17中文章的標題部分,可以發(fā)現標題的鏈接地址收錄“=.html”。因此,在“必須收錄”中,填寫(xiě)“=.html”。
  至此,“文章URL匹配規則”就設置好了。填寫(xiě)后,如圖(圖18),
  
  圖 18 - 文章 設置后的 URL 匹配規則
  通過(guò)以上三個(gè)小節,已經(jīng)設置了添加采集節點(diǎn)的第一步。設置后的最終結果,如圖(圖19),
  
  圖19 - 設置后新增采集節點(diǎn):第一步設置基本信息和URL索引頁(yè)面規則
  全部完成并勾選后,點(diǎn)擊“保存信息并進(jìn)入下一步”。如果前面設置正確,點(diǎn)擊后會(huì )進(jìn)入“添加采集節點(diǎn):測試URL索引頁(yè)面規則設置的基本信息和URL獲取規則測試”頁(yè)面,看到對應的文章列表地址. 如圖(圖20),
  
  圖 20 - URL 獲取規則測試
  確認無(wú)誤后,點(diǎn)擊“保存信息并進(jìn)入下一步”。否則,單擊“返回上一步進(jìn)行更改”。
  到這里,第一節就結束了。進(jìn)入下面的第二部分。. .

文章采集調用(跑到圖文加工店,說(shuō)給點(diǎn)素材,中年老板:騷年你來(lái)對了)

采集交流 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 141 次瀏覽 ? 2022-04-15 08:38 ? 來(lái)自相關(guān)話(huà)題

  文章采集調用(跑到圖文加工店,說(shuō)給點(diǎn)素材,中年老板:騷年你來(lái)對了)
  我去了圖形加工店,要了一些材料。中年老板:騷年,你說(shuō)得對,我們這里有很多存貨。我們擁有您需要的一切,無(wú)論是否為 JPG、PSD、AI、AE、AV……
  我去了菜市場(chǎng),給我舉了一些例子。水果賣(mài)家:朋友知道貨。今天剛到的李子很清爽。缺點(diǎn)是太甜了!隔壁賣(mài)糖炒栗子的小伙伸了伸脖子:大哥,帶個(gè)剛出鍋的袋子!
  嗯……定義很重要,所以我們今天說(shuō)的就是閱讀中獲得的文本內容,寫(xiě)作、演講、推理等參考和引用的材料和例子。
  其實(shí)很多大牛都寫(xiě)過(guò)管理自己的知識庫,整理自己的知識體系文章等文章,素材和例子只是其中很小的一部分。和那些大牛相比,這次我只關(guān)注材料和例子。這個(gè)入口點(diǎn)非常小。如果你已經(jīng)建立了自己完整的知識框架和結構,非常歡迎你給我意見(jiàn)和批評,面帶微笑。
  一、素材和例子有什么用1.征服觀(guān)眾
  在寫(xiě)作或演講時(shí),通常圍繞一個(gè)主題,你所要做的就是讓讀者或聽(tīng)眾理解并接受你所說(shuō)的話(huà)。如果你像教科書(shū)一樣一個(gè)一個(gè)地遵守規則,你可能會(huì )失去很多觀(guān)眾。這種情況在演講時(shí)尤其明顯。當你偶爾低頭在臺上尋求所謂的眼神交流和互動(dòng)感,發(fā)現臺下很多人都只是笑瞇瞇地盯著(zhù)桌子看,你應該明白你說(shuō)的沒(méi)那么有趣他們作為微博或朋友圈。
  適當的書(shū)面或口語(yǔ)引用可以幫助最大程度地防止這種情況發(fā)生。在寫(xiě)作中引用例子可以幫助讀者避免長(cháng)時(shí)間閱讀的疲勞,同時(shí)加深對內容的理解;演講中生動(dòng)的例子更有意義,使你表達的內容更容易被聽(tīng)眾接受和理解。此外,成人注意力的時(shí)間曲線(xiàn)有其特定的規律。舉兩個(gè)生動(dòng)的例子,在聽(tīng)眾精力下降、容易分心的時(shí)候,可以瞬間重新集中注意力,保證演講的良好效果。
  2.已關(guān)注
  你身邊應該有幾個(gè)這樣的朋友。飯桌上,談山,如切瓜切菜。上至天文地理玄學(xué)玄學(xué),三體四書(shū)五道口,下至官民悲喜肉離奇故事,五花八門(mén)。境界中,入流而不入流的,如果被TA接管了,也別想帶回去。如果你也想成為黨的中心(當然,最好排除個(gè)人自我宣傳的內容),一個(gè)反駁大片的引用,那么素材和例子的采集可以讓你玩得更輕松. 李笑來(lái)老師在《花時(shí)間做朋友》中提到,父親在公共場(chǎng)合總是能言善辯。一時(shí)間,他原以為父親是個(gè)記憶力極好的人,后來(lái)才發(fā)現,父親的秘密,其實(shí)是一本寫(xiě)滿(mǎn)記錄的筆記本。所謂口才,就是根據采集到的資料和例子,什么時(shí)候可以應用到什么場(chǎng)合。
  3.生理原因(個(gè)人原因)
  英語(yǔ)中有一句話(huà):在我的舌尖上,字面意思是“在我的舌尖上”。它實(shí)際上意味著(zhù)這些話(huà)在嘴唇上,但我突然想不起來(lái)了。在專(zhuān)注于采集資料和例子之前,我有很多類(lèi)似的經(jīng)歷。我清楚地記得,前一天,甚至幾個(gè)小時(shí)前,我碰巧看到了一個(gè)可以支持我觀(guān)點(diǎn)的例子,但我不記得細節和來(lái)源了。孤歌獨娘,沒(méi)有結果。這時(shí)候,我會(huì )感到后背和喉嚨有刺的不適感,相當難受。我認為這種感覺(jué)來(lái)自于沒(méi)有保存適當的材料或示例的遺憾。
  因此,采集和整理資料和例子已經(jīng)成為我的日常習慣之一?!皶?shū)籍只有在使用時(shí)才會(huì )被使用?!?古人早就發(fā)出過(guò)類(lèi)似的感嘆。事實(shí)上,對于掌握了很多新工具和新方法的現代人來(lái)說(shuō),采集和整理資料和實(shí)例其實(shí)并沒(méi)有想象中的那么麻煩。
  二、如何采集資料和例子1.采集資料和例子
  由于我說(shuō)的采集整理主要是針對文字內容,所以采集資料和例子的主要來(lái)源如下:
  (1)書(shū)籍
  如今,知識產(chǎn)權的保護普遍受到重視。很多書(shū)的內容不能直接在網(wǎng)上獲取,只能在閱讀后摘錄和總結。
  - 電子書(shū)
  目前國內外新書(shū)趨勢是電子版和紙質(zhì)版同步推出。電子版通常比較便宜,可以直接在亞馬遜等官網(wǎng)購買(mǎi)。尤其是剛出版的新書(shū),基本上只能找到付費版(各種號稱(chēng)免費的網(wǎng)站往往最后都指向付費版網(wǎng)址)。對于已經(jīng)上架一段時(shí)間的書(shū)籍,會(huì )有各種免費的電子版流出,其中大部分是PDF,但質(zhì)量參差不齊。還有一件事,我找電子書(shū)的建議是,如果5-10分鐘內沒(méi)有找到合適的版本,基本可以放棄。不值得花更多寶貴的時(shí)間在無(wú)法保證的免費和優(yōu)質(zhì)內容上,并直接購買(mǎi)電子書(shū)。版本性?xún)r(jià)比更高,付費也體現了對知識的尊重。
  以目前主流的亞馬遜官網(wǎng)為例,購買(mǎi)完成后會(huì )自動(dòng)推送到KINDLE。為了方便后續的整理和檢索,我會(huì )使用CALIBER軟件和DEDRM插件將亞馬遜下載的AZW3格式轉換成EPUB格式,然后把書(shū)放進(jìn)書(shū)里。所需內容采集在印象筆記中(僅供學(xué)習參考,絕不參與D版盈利),讓大量摘抄和引用的內容輕松復制到印象筆記保存和同步,不易丟失和容易搜索。
  - 紙質(zhì)書(shū)
  有的書(shū)比較經(jīng)典但年代久遠,多次再版都沒(méi)有電子版;還有非小說(shuō)類(lèi)的書(shū),因為我個(gè)人喜歡邊看書(shū)邊寫(xiě)讀書(shū)筆記,所以買(mǎi)了紙質(zhì)版。對于這種紙質(zhì)書(shū),做長(cháng)篇摘錄很不方便,手工摘錄也相當耗時(shí)。幸運的是,我在某寶上找到了一款手持掃描筆,可以快速將紙張內容掃描成可編輯的文本格式,比手動(dòng)輸入效率高出很多倍。以前看過(guò)萬(wàn)維剛的《沒(méi)想到》。其中有許多科學(xué)證據的例子。段落很長(cháng)。錢(qián)是不能存的。對于紙質(zhì)書(shū)閱讀量大、喜歡做閱讀筆記的朋友來(lái)說(shuō),掃描筆是個(gè)值得推薦的工具。
  (2)微信內容
  微信是大多數人使用頻率最高的手機應用,用得上不用說(shuō)。我關(guān)聯(lián)了印象筆記和有道云筆記這兩個(gè)官方微信賬號。我一般把值得采集的內容隨時(shí)保存在云端,然后在電腦上整理總結。
  (3)網(wǎng)頁(yè)內容
  當我瀏覽網(wǎng)頁(yè)時(shí),我也會(huì )保存我發(fā)現的好內容。復制粘貼部分太麻煩了。為此,我使用了印象筆記的網(wǎng)頁(yè)剪輯插件??梢赃x擇整頁(yè),網(wǎng)頁(yè)正文,或者去廣告等等,形式多樣,非常體貼。
  (4)其他
  其他來(lái)源不是我采集整理資料的主流渠道,比如微信聊天記錄等,我靠谷歌度娘的一些技巧整理成文字保存。
  2.材料和例子的組織
  采集后一定要整理好,否則起不到任何價(jià)值。整理的目的是為了更好的使用,單靠大腦很難把采集到的所有內容都記住。作為一個(gè)85后,我經(jīng)常聽(tīng)到90后說(shuō):“哎呀!怎么記不住了?年紀大了,腦子就不行了?!?更習慣了)。事實(shí)上,人的大腦就像一臺電腦。存儲容量有一定的上限。此外,人腦也有遺忘機制。對于長(cháng)時(shí)間不使用的內容,大腦會(huì )選擇忘記釋放存儲空間讓經(jīng)常使用的模塊運行。因此,我們需要將采集到的資料和實(shí)例進(jìn)行更有效的整理,以方便后續的高效調用,減輕大腦的負擔,
  以印象筆記為例。完成采集動(dòng)作后,你的印象筆記現在應該有相當多的內容了,但是它們是雜亂無(wú)章的。這時(shí)候,你需要做三件事:
  第一步是取名字。這是最直接的內容分類(lèi)方法,也是最原創(chuàng )的信息搜索渠道。我通常給內容命名的方式是:日期+類(lèi)型+一般內容摘要,例如:20161011知乎LIVE-詹老師——一種不需要意志力的習慣養成方法,這樣不管我怎么想“獵鷹”、“習慣”、“知乎”或日期,可以找到這個(gè)材料。
  第二步是分類(lèi)。采集到的內容按照類(lèi)型設置成文件夾并進(jìn)行相應分類(lèi),就像在電腦上為各種文檔創(chuàng )建文件夾一樣。我現在常用的文件夾有:個(gè)人(存放個(gè)人內容和其他私密內容,可選擇加密)、日常工作(與工作相關(guān)的資料或內容)、學(xué)習(與學(xué)習、寫(xiě)作、成長(cháng)等相關(guān))等。此設置的優(yōu)點(diǎn)是,當您不記得要搜索的具體內容,但可以確定需要查找的一般類(lèi)別時(shí),您可以過(guò)濾掉其他大類(lèi)并縮小搜索范圍。但是,當內容積累到一定程度時(shí),這樣的分類(lèi)范圍還是太粗,不夠細。此時(shí),
  第三步也是最重要的一步是添加標簽!標簽!標簽?。ㄖ匾氖虑檎f(shuō)三遍)按文件夾分類(lèi)的材料有一個(gè)巨大的缺陷。一份資料或例子只能歸入一個(gè)文件夾。如果要放到第二個(gè)文件夾,只能復制粘貼一次。. 數據本質(zhì)上是復雜的。復制粘貼會(huì )導致多個(gè)重復的搜索結果,并且會(huì )白白占用寶貴的云存儲空間。強烈不推薦。因此,此時(shí)需要對素材或示例做的是添加標簽,而不是添加一個(gè)標簽,而是添加盡可能多的標簽,并根據該素材所能窮盡的所有相關(guān)特性進(jìn)行標記. 例如:之前在簡(jiǎn)書(shū)上看到一篇文章文章《經(jīng)驗:我如何找到電子書(shū)》,它教你如何搜索你需要的電子書(shū)或電子版資料。我把這個(gè)文章按類(lèi)別放在study文件夾里,但其實(shí)我在工作中也用到了電子資料的搜索技巧。所以我給這個(gè)文章加了“e-book”、“search”、“resource”、“skill”等幾個(gè)標簽,方便以后寫(xiě)文章來(lái)明確調用資源,找電子書(shū),在普及工作技能等角度的時(shí)候可以找到這個(gè)文章。
  標記有兩個(gè)非常大的好處。首先,打標簽可以幫助你思考反芻:除了解釋原創(chuàng )內容之外,這個(gè)材料或例子還能用于哪些其他方面?它還可以用來(lái)支持哪些其他論點(diǎn)?這與上面提到的相同。李笑來(lái)老師和他的父親,通過(guò)記錄和思考,在什么時(shí)間、什么地點(diǎn)、什么情況下記下了筆記本上的內容。是“思維拓展”的簡(jiǎn)化版,也可以體現來(lái)這里幫助你進(jìn)一步理解內容。二是通過(guò)打標簽會(huì )有很多意想不到的“驚喜”。我之前寫(xiě)過(guò)《學(xué)會(huì )花錢(qián)》這本書(shū)的書(shū)評。當我分析涉及概率論的章節時(shí),我點(diǎn)擊了我標記為“
  三、調用的方法
  所謂調用就是搜索所有你認為你能想到的關(guān)鍵詞來(lái)找到你想要的內容,其中一些在上一篇文章中已經(jīng)提到過(guò)??梢源_定,文件名的搜索是最直接的。如果沒(méi)有,可以在大類(lèi)中搜索,縮小范圍,或者使用標簽疊加的方法進(jìn)行多維搜索。目前我最常用的方法是確定大類(lèi),然后使用多個(gè)標簽疊加搜索的方法,這種方法是最具方向性的。如果您想在搜索時(shí)獲得靈感,僅使用一個(gè)關(guān)鍵字瀏覽或單擊一組單獨的標簽通常會(huì )給您帶來(lái)意想不到的東西。
  李敖拆書(shū)的著(zhù)名例子就是材料采集和轉移的最好例子。以下文字來(lái)自對他的采訪(fǎng):
  我很少忘記讀過(guò)的書(shū),李敖,為什么?方法很好。有什么辦法?無(wú)情。所有的剪刀和美工刀都用了,當這本書(shū)被肢解時(shí),它被切開(kāi)。這個(gè)頁(yè)面我需要,這個(gè)段落我需要,我按類(lèi)別分開(kāi)。背面呢?復印一份,或者一開(kāi)始買(mǎi)兩本書(shū),剪開(kāi)整理一下,想看的部分留著(zhù)。結果一本書(shū)寫(xiě)完了,書(shū)也被肢解了。我就是這樣看書(shū)的。
  分類(lèi)是如何劃分的?我有很多自己制作的剪輯,我在剪輯上寫(xiě)下并分類(lèi)所有信息。讀完一本書(shū),全都進(jìn)了我的文件夾。我可以分出上千個(gè)班級,分得很細。例如,按照圖書(shū)館的分類(lèi),有哲學(xué)類(lèi)和宗教類(lèi);宗教類(lèi)別進(jìn)一步分為佛教、道教和天主教。我,李敖,可以分為更多的細節。天主教徒可以細分,神父是一類(lèi)。牧師也可以細分。同性戀神父是一類(lèi),世俗神父是另一類(lèi)。女同性戀是一類(lèi),修女是世俗的,是另一類(lèi)。
  書(shū)中的任何相關(guān)內容都會(huì )進(jìn)入我的個(gè)人資料。輸入什么?當我想寫(xiě)小說(shuō)時(shí),我需要這些信息,打開(kāi)信息,然后就寫(xiě)出來(lái)?;蛘甙l(fā)生了什么事,這與修女是同性戀有關(guān)。我想表達我對新聞的想法,帶來(lái)新聞,打開(kāi)我的數據,合并兩者,文章馬上就寫(xiě)出來(lái)。
  也就是說(shuō),看完這本書(shū),我被五匹馬撕成了八塊。但我被迷住了。我不記得這些材料。我小心翼翼地把它們掛起來(lái),放在文件夾里。我的記憶只需要記住這些標題。標題是根據我的習慣劃分的?;旧隙际欠g成英文單詞,排列成英文字母,偶爾也有一些中文。"
  四、備注
  在明確了材料采集的方法和好處之后,有兩點(diǎn)需要注意:
  1.確認是真的。
  邏輯中有一個(gè)重要的概念:“合乎邏輯就是符合真理”。如果采集的材料和例子來(lái)自歪曲事實(shí)或報道,那么即使它符合你的觀(guān)點(diǎn),支持你的說(shuō)法,也沒(méi)有任何意義,甚至會(huì )產(chǎn)生相反的效果,讓讀者或聽(tīng)眾覺(jué)得你是一個(gè)無(wú)法區分的人。對真假撒謊的人,從而大大降低了你觀(guān)點(diǎn)的可信度。此外,即使材料是真實(shí)的,也很可能是時(shí)間敏感的。因此,在使用素材或示例時(shí),一定要記得檢查內容是否真實(shí),是否仍然準確,并及時(shí)更新篩選。如果涉及收錄日期或數據的新聞、歷史、人文等,
  2.通知消息來(lái)源。
  引用示例時(shí),在不引用來(lái)源的情況下表達內容會(huì )讓人感到缺乏信任。如果讀者或聽(tīng)眾對您引用的材料或示例特別感興趣,他們可能希望通過(guò)這些資源了解更詳細的內容。因此,在引用資料或例子時(shí),盡量告知出處,同時(shí)不影響表達的流暢性。
  五、總結
  查看有關(guān)采集和組織示例的所需要點(diǎn):
  ——為什么要注意資料和例子的采集
  1.征服全場(chǎng)
  2.已關(guān)注
  3.(個(gè)人原因)
  - 采集和組織方法
  1.采集來(lái)源
  (1)書(shū)籍 - 電子版、紙質(zhì)版
  (2)微信
  (3) 網(wǎng)頁(yè)
  (4)其他
  - 調用方法
  文件名、類(lèi)別、標簽覆蓋
  - 防范措施
  1.確認真相
  2.通知來(lái)源
  話(huà)雖如此,我只是想把我采集整理的習慣分享給大家,讓分享好的東西更有意義。無(wú)論是寫(xiě)作、口語(yǔ)、推理,還是豐富對話(huà)、獲取知識,還是成為一個(gè)有趣的人,好的材料和例子都是非常有幫助的?!昂糜浶圆蝗鐗墓P”,在這個(gè)時(shí)代應該改為“好記性不如壞手指”。雖然一開(kāi)始可能看起來(lái)有些麻煩,但當你意識到經(jīng)常采集和整理的好處時(shí),你絕對不會(huì )停下來(lái)。想到通過(guò)采集整理,就可以控制這么大的素材庫供自己使用,是多么有趣啊。
  你為什么不也試試呢? 查看全部

  文章采集調用(跑到圖文加工店,說(shuō)給點(diǎn)素材,中年老板:騷年你來(lái)對了)
  我去了圖形加工店,要了一些材料。中年老板:騷年,你說(shuō)得對,我們這里有很多存貨。我們擁有您需要的一切,無(wú)論是否為 JPG、PSD、AI、AE、AV……
  我去了菜市場(chǎng),給我舉了一些例子。水果賣(mài)家:朋友知道貨。今天剛到的李子很清爽。缺點(diǎn)是太甜了!隔壁賣(mài)糖炒栗子的小伙伸了伸脖子:大哥,帶個(gè)剛出鍋的袋子!
  嗯……定義很重要,所以我們今天說(shuō)的就是閱讀中獲得的文本內容,寫(xiě)作、演講、推理等參考和引用的材料和例子。
  其實(shí)很多大牛都寫(xiě)過(guò)管理自己的知識庫,整理自己的知識體系文章等文章,素材和例子只是其中很小的一部分。和那些大牛相比,這次我只關(guān)注材料和例子。這個(gè)入口點(diǎn)非常小。如果你已經(jīng)建立了自己完整的知識框架和結構,非常歡迎你給我意見(jiàn)和批評,面帶微笑。
  一、素材和例子有什么用1.征服觀(guān)眾
  在寫(xiě)作或演講時(shí),通常圍繞一個(gè)主題,你所要做的就是讓讀者或聽(tīng)眾理解并接受你所說(shuō)的話(huà)。如果你像教科書(shū)一樣一個(gè)一個(gè)地遵守規則,你可能會(huì )失去很多觀(guān)眾。這種情況在演講時(shí)尤其明顯。當你偶爾低頭在臺上尋求所謂的眼神交流和互動(dòng)感,發(fā)現臺下很多人都只是笑瞇瞇地盯著(zhù)桌子看,你應該明白你說(shuō)的沒(méi)那么有趣他們作為微博或朋友圈。
  適當的書(shū)面或口語(yǔ)引用可以幫助最大程度地防止這種情況發(fā)生。在寫(xiě)作中引用例子可以幫助讀者避免長(cháng)時(shí)間閱讀的疲勞,同時(shí)加深對內容的理解;演講中生動(dòng)的例子更有意義,使你表達的內容更容易被聽(tīng)眾接受和理解。此外,成人注意力的時(shí)間曲線(xiàn)有其特定的規律。舉兩個(gè)生動(dòng)的例子,在聽(tīng)眾精力下降、容易分心的時(shí)候,可以瞬間重新集中注意力,保證演講的良好效果。
  2.已關(guān)注
  你身邊應該有幾個(gè)這樣的朋友。飯桌上,談山,如切瓜切菜。上至天文地理玄學(xué)玄學(xué),三體四書(shū)五道口,下至官民悲喜肉離奇故事,五花八門(mén)。境界中,入流而不入流的,如果被TA接管了,也別想帶回去。如果你也想成為黨的中心(當然,最好排除個(gè)人自我宣傳的內容),一個(gè)反駁大片的引用,那么素材和例子的采集可以讓你玩得更輕松. 李笑來(lái)老師在《花時(shí)間做朋友》中提到,父親在公共場(chǎng)合總是能言善辯。一時(shí)間,他原以為父親是個(gè)記憶力極好的人,后來(lái)才發(fā)現,父親的秘密,其實(shí)是一本寫(xiě)滿(mǎn)記錄的筆記本。所謂口才,就是根據采集到的資料和例子,什么時(shí)候可以應用到什么場(chǎng)合。
  3.生理原因(個(gè)人原因)
  英語(yǔ)中有一句話(huà):在我的舌尖上,字面意思是“在我的舌尖上”。它實(shí)際上意味著(zhù)這些話(huà)在嘴唇上,但我突然想不起來(lái)了。在專(zhuān)注于采集資料和例子之前,我有很多類(lèi)似的經(jīng)歷。我清楚地記得,前一天,甚至幾個(gè)小時(shí)前,我碰巧看到了一個(gè)可以支持我觀(guān)點(diǎn)的例子,但我不記得細節和來(lái)源了。孤歌獨娘,沒(méi)有結果。這時(shí)候,我會(huì )感到后背和喉嚨有刺的不適感,相當難受。我認為這種感覺(jué)來(lái)自于沒(méi)有保存適當的材料或示例的遺憾。
  因此,采集和整理資料和例子已經(jīng)成為我的日常習慣之一?!皶?shū)籍只有在使用時(shí)才會(huì )被使用?!?古人早就發(fā)出過(guò)類(lèi)似的感嘆。事實(shí)上,對于掌握了很多新工具和新方法的現代人來(lái)說(shuō),采集和整理資料和實(shí)例其實(shí)并沒(méi)有想象中的那么麻煩。
  二、如何采集資料和例子1.采集資料和例子
  由于我說(shuō)的采集整理主要是針對文字內容,所以采集資料和例子的主要來(lái)源如下:
  (1)書(shū)籍
  如今,知識產(chǎn)權的保護普遍受到重視。很多書(shū)的內容不能直接在網(wǎng)上獲取,只能在閱讀后摘錄和總結。
  - 電子書(shū)
  目前國內外新書(shū)趨勢是電子版和紙質(zhì)版同步推出。電子版通常比較便宜,可以直接在亞馬遜等官網(wǎng)購買(mǎi)。尤其是剛出版的新書(shū),基本上只能找到付費版(各種號稱(chēng)免費的網(wǎng)站往往最后都指向付費版網(wǎng)址)。對于已經(jīng)上架一段時(shí)間的書(shū)籍,會(huì )有各種免費的電子版流出,其中大部分是PDF,但質(zhì)量參差不齊。還有一件事,我找電子書(shū)的建議是,如果5-10分鐘內沒(méi)有找到合適的版本,基本可以放棄。不值得花更多寶貴的時(shí)間在無(wú)法保證的免費和優(yōu)質(zhì)內容上,并直接購買(mǎi)電子書(shū)。版本性?xún)r(jià)比更高,付費也體現了對知識的尊重。
  以目前主流的亞馬遜官網(wǎng)為例,購買(mǎi)完成后會(huì )自動(dòng)推送到KINDLE。為了方便后續的整理和檢索,我會(huì )使用CALIBER軟件和DEDRM插件將亞馬遜下載的AZW3格式轉換成EPUB格式,然后把書(shū)放進(jìn)書(shū)里。所需內容采集在印象筆記中(僅供學(xué)習參考,絕不參與D版盈利),讓大量摘抄和引用的內容輕松復制到印象筆記保存和同步,不易丟失和容易搜索。
  - 紙質(zhì)書(shū)
  有的書(shū)比較經(jīng)典但年代久遠,多次再版都沒(méi)有電子版;還有非小說(shuō)類(lèi)的書(shū),因為我個(gè)人喜歡邊看書(shū)邊寫(xiě)讀書(shū)筆記,所以買(mǎi)了紙質(zhì)版。對于這種紙質(zhì)書(shū),做長(cháng)篇摘錄很不方便,手工摘錄也相當耗時(shí)。幸運的是,我在某寶上找到了一款手持掃描筆,可以快速將紙張內容掃描成可編輯的文本格式,比手動(dòng)輸入效率高出很多倍。以前看過(guò)萬(wàn)維剛的《沒(méi)想到》。其中有許多科學(xué)證據的例子。段落很長(cháng)。錢(qián)是不能存的。對于紙質(zhì)書(shū)閱讀量大、喜歡做閱讀筆記的朋友來(lái)說(shuō),掃描筆是個(gè)值得推薦的工具。
  (2)微信內容
  微信是大多數人使用頻率最高的手機應用,用得上不用說(shuō)。我關(guān)聯(lián)了印象筆記和有道云筆記這兩個(gè)官方微信賬號。我一般把值得采集的內容隨時(shí)保存在云端,然后在電腦上整理總結。
  (3)網(wǎng)頁(yè)內容
  當我瀏覽網(wǎng)頁(yè)時(shí),我也會(huì )保存我發(fā)現的好內容。復制粘貼部分太麻煩了。為此,我使用了印象筆記的網(wǎng)頁(yè)剪輯插件??梢赃x擇整頁(yè),網(wǎng)頁(yè)正文,或者去廣告等等,形式多樣,非常體貼。
  (4)其他
  其他來(lái)源不是我采集整理資料的主流渠道,比如微信聊天記錄等,我靠谷歌度娘的一些技巧整理成文字保存。
  2.材料和例子的組織
  采集后一定要整理好,否則起不到任何價(jià)值。整理的目的是為了更好的使用,單靠大腦很難把采集到的所有內容都記住。作為一個(gè)85后,我經(jīng)常聽(tīng)到90后說(shuō):“哎呀!怎么記不住了?年紀大了,腦子就不行了?!?更習慣了)。事實(shí)上,人的大腦就像一臺電腦。存儲容量有一定的上限。此外,人腦也有遺忘機制。對于長(cháng)時(shí)間不使用的內容,大腦會(huì )選擇忘記釋放存儲空間讓經(jīng)常使用的模塊運行。因此,我們需要將采集到的資料和實(shí)例進(jìn)行更有效的整理,以方便后續的高效調用,減輕大腦的負擔,
  以印象筆記為例。完成采集動(dòng)作后,你的印象筆記現在應該有相當多的內容了,但是它們是雜亂無(wú)章的。這時(shí)候,你需要做三件事:
  第一步是取名字。這是最直接的內容分類(lèi)方法,也是最原創(chuàng )的信息搜索渠道。我通常給內容命名的方式是:日期+類(lèi)型+一般內容摘要,例如:20161011知乎LIVE-詹老師——一種不需要意志力的習慣養成方法,這樣不管我怎么想“獵鷹”、“習慣”、“知乎”或日期,可以找到這個(gè)材料。
  第二步是分類(lèi)。采集到的內容按照類(lèi)型設置成文件夾并進(jìn)行相應分類(lèi),就像在電腦上為各種文檔創(chuàng )建文件夾一樣。我現在常用的文件夾有:個(gè)人(存放個(gè)人內容和其他私密內容,可選擇加密)、日常工作(與工作相關(guān)的資料或內容)、學(xué)習(與學(xué)習、寫(xiě)作、成長(cháng)等相關(guān))等。此設置的優(yōu)點(diǎn)是,當您不記得要搜索的具體內容,但可以確定需要查找的一般類(lèi)別時(shí),您可以過(guò)濾掉其他大類(lèi)并縮小搜索范圍。但是,當內容積累到一定程度時(shí),這樣的分類(lèi)范圍還是太粗,不夠細。此時(shí),
  第三步也是最重要的一步是添加標簽!標簽!標簽?。ㄖ匾氖虑檎f(shuō)三遍)按文件夾分類(lèi)的材料有一個(gè)巨大的缺陷。一份資料或例子只能歸入一個(gè)文件夾。如果要放到第二個(gè)文件夾,只能復制粘貼一次。. 數據本質(zhì)上是復雜的。復制粘貼會(huì )導致多個(gè)重復的搜索結果,并且會(huì )白白占用寶貴的云存儲空間。強烈不推薦。因此,此時(shí)需要對素材或示例做的是添加標簽,而不是添加一個(gè)標簽,而是添加盡可能多的標簽,并根據該素材所能窮盡的所有相關(guān)特性進(jìn)行標記. 例如:之前在簡(jiǎn)書(shū)上看到一篇文章文章《經(jīng)驗:我如何找到電子書(shū)》,它教你如何搜索你需要的電子書(shū)或電子版資料。我把這個(gè)文章按類(lèi)別放在study文件夾里,但其實(shí)我在工作中也用到了電子資料的搜索技巧。所以我給這個(gè)文章加了“e-book”、“search”、“resource”、“skill”等幾個(gè)標簽,方便以后寫(xiě)文章來(lái)明確調用資源,找電子書(shū),在普及工作技能等角度的時(shí)候可以找到這個(gè)文章。
  標記有兩個(gè)非常大的好處。首先,打標簽可以幫助你思考反芻:除了解釋原創(chuàng )內容之外,這個(gè)材料或例子還能用于哪些其他方面?它還可以用來(lái)支持哪些其他論點(diǎn)?這與上面提到的相同。李笑來(lái)老師和他的父親,通過(guò)記錄和思考,在什么時(shí)間、什么地點(diǎn)、什么情況下記下了筆記本上的內容。是“思維拓展”的簡(jiǎn)化版,也可以體現來(lái)這里幫助你進(jìn)一步理解內容。二是通過(guò)打標簽會(huì )有很多意想不到的“驚喜”。我之前寫(xiě)過(guò)《學(xué)會(huì )花錢(qián)》這本書(shū)的書(shū)評。當我分析涉及概率論的章節時(shí),我點(diǎn)擊了我標記為“
  三、調用的方法
  所謂調用就是搜索所有你認為你能想到的關(guān)鍵詞來(lái)找到你想要的內容,其中一些在上一篇文章中已經(jīng)提到過(guò)??梢源_定,文件名的搜索是最直接的。如果沒(méi)有,可以在大類(lèi)中搜索,縮小范圍,或者使用標簽疊加的方法進(jìn)行多維搜索。目前我最常用的方法是確定大類(lèi),然后使用多個(gè)標簽疊加搜索的方法,這種方法是最具方向性的。如果您想在搜索時(shí)獲得靈感,僅使用一個(gè)關(guān)鍵字瀏覽或單擊一組單獨的標簽通常會(huì )給您帶來(lái)意想不到的東西。
  李敖拆書(shū)的著(zhù)名例子就是材料采集和轉移的最好例子。以下文字來(lái)自對他的采訪(fǎng):
  我很少忘記讀過(guò)的書(shū),李敖,為什么?方法很好。有什么辦法?無(wú)情。所有的剪刀和美工刀都用了,當這本書(shū)被肢解時(shí),它被切開(kāi)。這個(gè)頁(yè)面我需要,這個(gè)段落我需要,我按類(lèi)別分開(kāi)。背面呢?復印一份,或者一開(kāi)始買(mǎi)兩本書(shū),剪開(kāi)整理一下,想看的部分留著(zhù)。結果一本書(shū)寫(xiě)完了,書(shū)也被肢解了。我就是這樣看書(shū)的。
  分類(lèi)是如何劃分的?我有很多自己制作的剪輯,我在剪輯上寫(xiě)下并分類(lèi)所有信息。讀完一本書(shū),全都進(jìn)了我的文件夾。我可以分出上千個(gè)班級,分得很細。例如,按照圖書(shū)館的分類(lèi),有哲學(xué)類(lèi)和宗教類(lèi);宗教類(lèi)別進(jìn)一步分為佛教、道教和天主教。我,李敖,可以分為更多的細節。天主教徒可以細分,神父是一類(lèi)。牧師也可以細分。同性戀神父是一類(lèi),世俗神父是另一類(lèi)。女同性戀是一類(lèi),修女是世俗的,是另一類(lèi)。
  書(shū)中的任何相關(guān)內容都會(huì )進(jìn)入我的個(gè)人資料。輸入什么?當我想寫(xiě)小說(shuō)時(shí),我需要這些信息,打開(kāi)信息,然后就寫(xiě)出來(lái)?;蛘甙l(fā)生了什么事,這與修女是同性戀有關(guān)。我想表達我對新聞的想法,帶來(lái)新聞,打開(kāi)我的數據,合并兩者,文章馬上就寫(xiě)出來(lái)。
  也就是說(shuō),看完這本書(shū),我被五匹馬撕成了八塊。但我被迷住了。我不記得這些材料。我小心翼翼地把它們掛起來(lái),放在文件夾里。我的記憶只需要記住這些標題。標題是根據我的習慣劃分的?;旧隙际欠g成英文單詞,排列成英文字母,偶爾也有一些中文。"
  四、備注
  在明確了材料采集的方法和好處之后,有兩點(diǎn)需要注意:
  1.確認是真的。
  邏輯中有一個(gè)重要的概念:“合乎邏輯就是符合真理”。如果采集的材料和例子來(lái)自歪曲事實(shí)或報道,那么即使它符合你的觀(guān)點(diǎn),支持你的說(shuō)法,也沒(méi)有任何意義,甚至會(huì )產(chǎn)生相反的效果,讓讀者或聽(tīng)眾覺(jué)得你是一個(gè)無(wú)法區分的人。對真假撒謊的人,從而大大降低了你觀(guān)點(diǎn)的可信度。此外,即使材料是真實(shí)的,也很可能是時(shí)間敏感的。因此,在使用素材或示例時(shí),一定要記得檢查內容是否真實(shí),是否仍然準確,并及時(shí)更新篩選。如果涉及收錄日期或數據的新聞、歷史、人文等,
  2.通知消息來(lái)源。
  引用示例時(shí),在不引用來(lái)源的情況下表達內容會(huì )讓人感到缺乏信任。如果讀者或聽(tīng)眾對您引用的材料或示例特別感興趣,他們可能希望通過(guò)這些資源了解更詳細的內容。因此,在引用資料或例子時(shí),盡量告知出處,同時(shí)不影響表達的流暢性。
  五、總結
  查看有關(guān)采集和組織示例的所需要點(diǎn):
  ——為什么要注意資料和例子的采集
  1.征服全場(chǎng)
  2.已關(guān)注
  3.(個(gè)人原因)
  - 采集和組織方法
  1.采集來(lái)源
  (1)書(shū)籍 - 電子版、紙質(zhì)版
  (2)微信
  (3) 網(wǎng)頁(yè)
  (4)其他
  - 調用方法
  文件名、類(lèi)別、標簽覆蓋
  - 防范措施
  1.確認真相
  2.通知來(lái)源
  話(huà)雖如此,我只是想把我采集整理的習慣分享給大家,讓分享好的東西更有意義。無(wú)論是寫(xiě)作、口語(yǔ)、推理,還是豐富對話(huà)、獲取知識,還是成為一個(gè)有趣的人,好的材料和例子都是非常有幫助的?!昂糜浶圆蝗鐗墓P”,在這個(gè)時(shí)代應該改為“好記性不如壞手指”。雖然一開(kāi)始可能看起來(lái)有些麻煩,但當你意識到經(jīng)常采集和整理的好處時(shí),你絕對不會(huì )停下來(lái)。想到通過(guò)采集整理,就可以控制這么大的素材庫供自己使用,是多么有趣啊。
  你為什么不也試試呢?

文章采集調用(注意事項雷電模擬器要用3.96.0版本的,用7.1版本我的思路)

采集交流 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 141 次瀏覽 ? 2022-04-14 20:26 ? 來(lái)自相關(guān)話(huà)題

  文章采集調用(注意事項雷電模擬器要用3.96.0版本的,用7.1版本我的思路)
  一、算法
  算法確實(shí)好用,但是破解的難度大家應該都知道。隨著(zhù)版本的更新,算法會(huì )經(jīng)常發(fā)生變化,你的軟件也會(huì )隨著(zhù)變化而更新,這樣會(huì )增加開(kāi)發(fā)成本。,你不得不說(shuō)采集效率!就個(gè)人而言,我不認為它快得多。畢竟,訪(fǎng)問(wèn)的頻率也是有限的。訪(fǎng)問(wèn)后不能更改代理,對嗎?這個(gè)多少錢(qián)?
  二、瀏覽器
  不知道大家有沒(méi)有發(fā)現,用戶(hù)的主頁(yè)是用瀏覽器打開(kāi)的,但是用戶(hù)的作品卻完全沒(méi)有顯示出來(lái)。相信很多人的算法都是通過(guò)網(wǎng)頁(yè)版獲取的,所以這就造成了一個(gè)現象,網(wǎng)頁(yè)版的算法,往往需要多次請求才能返回一組數據。當然,不排除有通過(guò)APP逆向獲得的大神。這種情況我就不在這里討論了,因為我也是半桶水倒過(guò)來(lái)。
  三、捕獲(提琴手)
  Fiddler 可以說(shuō)是 TCP 之外非常常見(jiàn)的抓包工具。證書(shū)安裝好后,什么都不用做。缺點(diǎn)是沒(méi)有API可以調用,除非你重新開(kāi)發(fā)。一個(gè)調用第三方的dll庫,我們在自己的程序中調用這個(gè)dll,把自己當做代理服務(wù)器,所有經(jīng)過(guò)的請求都會(huì )先經(jīng)過(guò)我這邊,這樣我就可以處理數據了。
  四、備注
  迅雷模擬器使用3.96.0版本,apk使用7.1版本
  我的思路:
  1.使用Fiddler做代理服務(wù)器,具體代碼和dll庫可以百度。
  
  2.用模擬器操作,安裝證書(shū),掛代理,你刷你的視頻,我的服務(wù)器會(huì )自動(dòng)過(guò)濾數據,留下有用的
  (1)配置模擬器,模擬器選擇手機版本,分辨率可選
  
  (2)使用模擬器中的瀏覽器打開(kāi)軟件上的鏈接(地址:端口),例如(192.168.0.109:8888)@ &gt; 繼續安裝證書(shū)
  
  (3)配置模擬器網(wǎng)絡(luò )代理
  
  就這么簡(jiǎn)單,不知道你看懂Get了嗎?這個(gè)方法,不管你放在什么app上,都是可行的,只要你要抓的數據是通過(guò)http或者https傳輸的,那么這個(gè)方法是可以的,但是在模擬器段,你可能要寫(xiě)一個(gè)腳本操作請求的觸發(fā)器。與破解算法相比,自動(dòng)化腳本可不是小菜一碟。
  關(guān)于抖音在模擬器中無(wú)法正常顯示數據,可以下載7.1版本的apk,不屏蔽模擬器的7.1版本。
  這是我自己的批量去水印下載的示例。有興趣的可以自行下載試用。有問(wèn)題或者需要更多功能可以私信我交流。下載后右鍵屬性解鎖,否則可能無(wú)法正常使用。
  對了,win7系統可能不行,因為很多win7 Fiddler證書(shū)無(wú)法正常安裝,所以軟件不能抓取https,這個(gè)可以自己測試。 查看全部

  文章采集調用(注意事項雷電模擬器要用3.96.0版本的,用7.1版本我的思路)
  一、算法
  算法確實(shí)好用,但是破解的難度大家應該都知道。隨著(zhù)版本的更新,算法會(huì )經(jīng)常發(fā)生變化,你的軟件也會(huì )隨著(zhù)變化而更新,這樣會(huì )增加開(kāi)發(fā)成本。,你不得不說(shuō)采集效率!就個(gè)人而言,我不認為它快得多。畢竟,訪(fǎng)問(wèn)的頻率也是有限的。訪(fǎng)問(wèn)后不能更改代理,對嗎?這個(gè)多少錢(qián)?
  二、瀏覽器
  不知道大家有沒(méi)有發(fā)現,用戶(hù)的主頁(yè)是用瀏覽器打開(kāi)的,但是用戶(hù)的作品卻完全沒(méi)有顯示出來(lái)。相信很多人的算法都是通過(guò)網(wǎng)頁(yè)版獲取的,所以這就造成了一個(gè)現象,網(wǎng)頁(yè)版的算法,往往需要多次請求才能返回一組數據。當然,不排除有通過(guò)APP逆向獲得的大神。這種情況我就不在這里討論了,因為我也是半桶水倒過(guò)來(lái)。
  三、捕獲(提琴手)
  Fiddler 可以說(shuō)是 TCP 之外非常常見(jiàn)的抓包工具。證書(shū)安裝好后,什么都不用做。缺點(diǎn)是沒(méi)有API可以調用,除非你重新開(kāi)發(fā)。一個(gè)調用第三方的dll庫,我們在自己的程序中調用這個(gè)dll,把自己當做代理服務(wù)器,所有經(jīng)過(guò)的請求都會(huì )先經(jīng)過(guò)我這邊,這樣我就可以處理數據了。
  四、備注
  迅雷模擬器使用3.96.0版本,apk使用7.1版本
  我的思路:
  1.使用Fiddler做代理服務(wù)器,具體代碼和dll庫可以百度。
  
  2.用模擬器操作,安裝證書(shū),掛代理,你刷你的視頻,我的服務(wù)器會(huì )自動(dòng)過(guò)濾數據,留下有用的
  (1)配置模擬器,模擬器選擇手機版本,分辨率可選
  
  (2)使用模擬器中的瀏覽器打開(kāi)軟件上的鏈接(地址:端口),例如(192.168.0.109:8888)@ &gt; 繼續安裝證書(shū)
  
  (3)配置模擬器網(wǎng)絡(luò )代理
  
  就這么簡(jiǎn)單,不知道你看懂Get了嗎?這個(gè)方法,不管你放在什么app上,都是可行的,只要你要抓的數據是通過(guò)http或者https傳輸的,那么這個(gè)方法是可以的,但是在模擬器段,你可能要寫(xiě)一個(gè)腳本操作請求的觸發(fā)器。與破解算法相比,自動(dòng)化腳本可不是小菜一碟。
  關(guān)于抖音在模擬器中無(wú)法正常顯示數據,可以下載7.1版本的apk,不屏蔽模擬器的7.1版本。
  這是我自己的批量去水印下載的示例。有興趣的可以自行下載試用。有問(wèn)題或者需要更多功能可以私信我交流。下載后右鍵屬性解鎖,否則可能無(wú)法正常使用。
  對了,win7系統可能不行,因為很多win7 Fiddler證書(shū)無(wú)法正常安裝,所以軟件不能抓取https,這個(gè)可以自己測試。

文章采集調用(2.采集支持調用奶盤(pán)API接口(組圖)采集數據 )

采集交流 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 155 次瀏覽 ? 2022-04-14 17:06 ? 來(lái)自相關(guān)話(huà)題

  文章采集調用(2.采集支持調用奶盤(pán)API接口(組圖)采集數據
)
  優(yōu)采云采集支持調用奶盤(pán)API接口,處理采集的數據標題和內容等;
  溫馨提示:第三方API接入功能需要用戶(hù)提供第三方接口賬號信息(即用戶(hù)需要注冊第三方接口,調用第三方接口產(chǎn)生的一切費用自理)由用戶(hù));
  詳細使用步驟
  1. 創(chuàng )建奶盤(pán)API接口配置一、API配置入口:
  點(diǎn)擊控制臺左側列表中的【第三方服務(wù)配置】==點(diǎn)擊【第三方內容API接入】==點(diǎn)擊【第三方API配置管理】==最后點(diǎn)擊【奶鍋】 Open API] 創(chuàng )建接口配置;
  
  二、配置API接口信息:
  【Purchased Authorized User】和【Purchased Authorization Code】是從后臺獲取API授權信息,填寫(xiě)優(yōu)采云;
  【API版】是奶鍋網(wǎng)購買(mǎi)對應的套餐:百度優(yōu)化版、AI智能版;
  
  
  注意:由于牛奶托盤(pán)每次調用限制為最多65000個(gè)字符(包括html代碼),當內容長(cháng)度超過(guò)時(shí),優(yōu)采云會(huì )被分割多次調用。這個(gè)操作會(huì )增加api調用次數,開(kāi)銷(xiāo)也會(huì )相應增加。這是用戶(hù)需要承擔的成本。使用前一定要注意?。?!
  2. 創(chuàng )建 API 處理規則
  API處理規則,可以通過(guò)調用API接口設置處理哪些字段的內容;
  一、API處理規則入口:
  點(diǎn)擊控制臺左側列表中的【第三方服務(wù)配置】==,點(diǎn)擊【第三方內容API接入】==進(jìn)入【API處理規則管理】頁(yè)面,最后點(diǎn)擊【+添加API處理規則]創(chuàng )建API處理規則;
  
  二、API處理規則配置:
  
  3. API 處理規則使用
  API處理規則有兩種使用方式:手動(dòng)執行和自動(dòng)執行:
  一、手動(dòng)執行API處理規則:
  在采集任務(wù)的【結果數據&amp;發(fā)布】選項卡中,點(diǎn)擊【SEO&amp;API&amp;翻譯等工具】按鈕==選擇【第三方API執行】欄==選擇對應的API處理規則= ="執行(數據范圍有兩種執行方式,根據發(fā)布狀態(tài)批量執行和根據列表中選擇的數據執行);
  
  二、自動(dòng)執行API處理規則:
  
  啟用 API 處理的自動(dòng)執行。任務(wù)完成后采集會(huì )自動(dòng)執行API處理。一般配合定時(shí)采集和自動(dòng)發(fā)布功能使用非常方便;
  在任務(wù)的【自動(dòng)化:發(fā)布&amp;SEO&amp;翻譯】選項卡【自動(dòng)執行第三方API配置】==勾選【采集,自動(dòng)執行API】選項==選擇要執行的API處理規則= ="選擇API接口處理的數據范圍(一般選擇'待釋放',all會(huì )導致所有數據重復執行),最后點(diǎn)擊保存;
  4. API處理結果并發(fā)布一、查看API接口處理結果:
  API接口處理后的內容會(huì )保存為一個(gè)新的字段,如:標題處理后的新字段:`title_milk tray`,內容處理后的新字段:`content_milk tray`,在【結果數據&amp;發(fā)布】和可以查看數據預覽界面。
  提示:執行 API 處理規則需要一段時(shí)間。執行完成后,頁(yè)面會(huì )自動(dòng)刷新,并出現API接口處理的新字段;
  
  二、API接口處理后的內容發(fā)布
  發(fā)布文章前,修改發(fā)布目標第二步的映射字段,重新選擇標題和內容到API接口處理后添加的對應字段`title_milk tray'和`content_milk tray';
  
  提示:如果發(fā)布目標中無(wú)法選擇新字段,請在任務(wù)下復制或新建發(fā)布目標,然后在新發(fā)布目標中選擇新字段即可。詳細教程請參考發(fā)布目標中不能選擇的字段。
  5. 奶盤(pán)-API接口常見(jiàn)問(wèn)題及解決方法一、API處理規則和SEO規則如何結合使用?
  系統默認對title和content字段進(jìn)行SEO功能,需要修改為SEO規則中的`title_milk tray'和`content_milk tray'字段;
   查看全部

  文章采集調用(2.采集支持調用奶盤(pán)API接口(組圖)采集數據
)
  優(yōu)采云采集支持調用奶盤(pán)API接口,處理采集的數據標題和內容等;
  溫馨提示:第三方API接入功能需要用戶(hù)提供第三方接口賬號信息(即用戶(hù)需要注冊第三方接口,調用第三方接口產(chǎn)生的一切費用自理)由用戶(hù));
  詳細使用步驟
  1. 創(chuàng )建奶盤(pán)API接口配置一、API配置入口:
  點(diǎn)擊控制臺左側列表中的【第三方服務(wù)配置】==點(diǎn)擊【第三方內容API接入】==點(diǎn)擊【第三方API配置管理】==最后點(diǎn)擊【奶鍋】 Open API] 創(chuàng )建接口配置;
  
  二、配置API接口信息:
  【Purchased Authorized User】和【Purchased Authorization Code】是從后臺獲取API授權信息,填寫(xiě)優(yōu)采云;
  【API版】是奶鍋網(wǎng)購買(mǎi)對應的套餐:百度優(yōu)化版、AI智能版;
  
  
  注意:由于牛奶托盤(pán)每次調用限制為最多65000個(gè)字符(包括html代碼),當內容長(cháng)度超過(guò)時(shí),優(yōu)采云會(huì )被分割多次調用。這個(gè)操作會(huì )增加api調用次數,開(kāi)銷(xiāo)也會(huì )相應增加。這是用戶(hù)需要承擔的成本。使用前一定要注意?。?!
  2. 創(chuàng )建 API 處理規則
  API處理規則,可以通過(guò)調用API接口設置處理哪些字段的內容;
  一、API處理規則入口:
  點(diǎn)擊控制臺左側列表中的【第三方服務(wù)配置】==,點(diǎn)擊【第三方內容API接入】==進(jìn)入【API處理規則管理】頁(yè)面,最后點(diǎn)擊【+添加API處理規則]創(chuàng )建API處理規則;
  
  二、API處理規則配置:
  
  3. API 處理規則使用
  API處理規則有兩種使用方式:手動(dòng)執行和自動(dòng)執行:
  一、手動(dòng)執行API處理規則:
  在采集任務(wù)的【結果數據&amp;發(fā)布】選項卡中,點(diǎn)擊【SEO&amp;API&amp;翻譯等工具】按鈕==選擇【第三方API執行】欄==選擇對應的API處理規則= ="執行(數據范圍有兩種執行方式,根據發(fā)布狀態(tài)批量執行和根據列表中選擇的數據執行);
  
  二、自動(dòng)執行API處理規則:
  
  啟用 API 處理的自動(dòng)執行。任務(wù)完成后采集會(huì )自動(dòng)執行API處理。一般配合定時(shí)采集和自動(dòng)發(fā)布功能使用非常方便;
  在任務(wù)的【自動(dòng)化:發(fā)布&amp;SEO&amp;翻譯】選項卡【自動(dòng)執行第三方API配置】==勾選【采集,自動(dòng)執行API】選項==選擇要執行的API處理規則= ="選擇API接口處理的數據范圍(一般選擇'待釋放',all會(huì )導致所有數據重復執行),最后點(diǎn)擊保存;
  4. API處理結果并發(fā)布一、查看API接口處理結果:
  API接口處理后的內容會(huì )保存為一個(gè)新的字段,如:標題處理后的新字段:`title_milk tray`,內容處理后的新字段:`content_milk tray`,在【結果數據&amp;發(fā)布】和可以查看數據預覽界面。
  提示:執行 API 處理規則需要一段時(shí)間。執行完成后,頁(yè)面會(huì )自動(dòng)刷新,并出現API接口處理的新字段;
  
  二、API接口處理后的內容發(fā)布
  發(fā)布文章前,修改發(fā)布目標第二步的映射字段,重新選擇標題和內容到API接口處理后添加的對應字段`title_milk tray'和`content_milk tray';
  
  提示:如果發(fā)布目標中無(wú)法選擇新字段,請在任務(wù)下復制或新建發(fā)布目標,然后在新發(fā)布目標中選擇新字段即可。詳細教程請參考發(fā)布目標中不能選擇的字段。
  5. 奶盤(pán)-API接口常見(jiàn)問(wèn)題及解決方法一、API處理規則和SEO規則如何結合使用?
  系統默認對title和content字段進(jìn)行SEO功能,需要修改為SEO規則中的`title_milk tray'和`content_milk tray'字段;
  

文章采集調用( 開(kāi)發(fā)環(huán)境JDK1.8.0javassist本章本章GA本章涉及源碼的開(kāi)發(fā))

采集交流 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 129 次瀏覽 ? 2022-04-13 14:15 ? 來(lái)自相關(guān)話(huà)題

  文章采集調用(
開(kāi)發(fā)環(huán)境JDK1.8.0javassist本章本章GA本章涉及源碼的開(kāi)發(fā))
  
  一、前言
  字節碼編程插樁技術(shù)常結合Javaagent技術(shù)用于系統的非侵入式監控,可以替代方法中的硬編碼操作。例如,您需要監控一個(gè)方法,包括;方法信息、執行時(shí)間、輸入輸出參數、執行鏈接、異常。那么就非常適合用這樣的技術(shù)手段進(jìn)行加工。
  為了體現這部分的核心內容,本文將只使用Javassist技術(shù)對一段方法字節碼進(jìn)行instrument,最后輸出該方法的執行信息,如下;
  Method - 后續字節碼增強操作的測試方法
  public Integer strToInt(String str01, String str02) {
return Integer.parseInt(str01);
}
  監控 - 方法的字節碼增強后,輸出監控信息
  監控 - Begin
方法:org.itstack.demo.javassist.ApiTest.strToInt
入參:["str01","str02"] 入參[類(lèi)型]:["java.lang.String","java.lang.String"] 入數[值]:["1","2"]
出參:java.lang.Integer 出參[值]:1
耗時(shí):59(s)
監控 - End
  有了這樣的監控方案,我們基本上可以輸出方法執行過(guò)程中的所有信息。然后通過(guò)后期的改進(jìn),將監控信息顯示在界面上,并實(shí)時(shí)發(fā)出警報。不僅提高了系統的監控質(zhì)量,也便于研發(fā)排查和定位問(wèn)題。
  這很好!然后我們一步步開(kāi)始使用javassist進(jìn)行字節碼插樁,就達到了我們的監控效果。
  二、開(kāi)發(fā)環(huán)境JDK 1.8.0javassist 3.12.1.GA本章涉及的源碼為:itstack-demo-bytecode -1-04,可以關(guān)注公眾號:bugstack 蟲(chóng)洞棧,回復源碼下載即可。您將獲得下載鏈接列表。打開(kāi)后第十七期“因為我有很多開(kāi)源代碼”,記得給個(gè)Star!三、技術(shù)實(shí)現1. 獲取方法的基本信息1.1 獲取類(lèi)
  ClassPool pool = ClassPool.getDefault();
// 獲取類(lèi)
CtClass ctClass = pool.get(org.itstack.demo.javassist.ApiTest.class.getName());
ctClass.replaceClassName("ApiTest", "ApiTest02");
String clazzName = ctClass.getName();
  通過(guò)類(lèi)名獲取類(lèi)信息,這里可以替換類(lèi)名。它還包括一些其他操作來(lái)獲取類(lèi)中的屬性,例如;ctClass.getSimpleName()、ctClass.getAnnotations() 等等。
  1.2 如何獲得
  CtMethod ctMethod = ctClass.getDeclaredMethod("strToInt");
String methodName = ctMethod.getName();
  通過(guò)getDeclaredMethod獲取方法的CtMethod的內容。之后,您可以獲取方法名稱(chēng)等信息。
  1.3 方法信息
  MethodInfo methodInfo = ctMethod.getMethodInfo();
  MethodInfo 收錄方法信息;名稱(chēng)、類(lèi)型等
  1.4 種方法類(lèi)型
  boolean isStatic = (methodInfo.getAccessFlags() & AccessFlag.STATIC) != 0;
  通過(guò)methodInfo.getAccessFlags()獲取方法的標識符,然后使用AND運算AccessFlag.STATIC判斷該方法是否為靜態(tài)方法。因為靜態(tài)方法會(huì )影響后續參數名的獲取,所以靜態(tài)方法的第一個(gè)參數就是this,需要排除。
  1.5 方法:輸入參數信息{name and type}
  CodeAttribute codeAttribute = methodInfo.getCodeAttribute();
LocalVariableAttribute attr = (LocalVariableAttribute) codeAttribute.getAttribute(LocalVariableAttribute.tag);
CtClass[] parameterTypes = ctMethod.getParameterTypes();
  1.6 方法;參數信息
  CtClass returnType = ctMethod.getReturnType();
String returnTypeName = returnType.getName();
  對于方法的參數信息,只需要獲取參數類(lèi)型即可。
  1.7 輸出所有獲取的信息
  System.out.println("類(lèi)名:" + clazzName);
System.out.println("方法:" + methodName);
System.out.println("類(lèi)型:" + (isStatic ? "靜態(tài)方法" : "非靜態(tài)方法"));
System.out.println("描述:" + methodInfo.getDescriptor());
System.out.println("入參[名稱(chēng)]:" + attr.variableName(1) + "," + attr.variableName(2));
System.out.println("入參[類(lèi)型]:" + parameterTypes[0].getName() + "," + parameterTypes[1].getName());
System.out.println("出參[類(lèi)型]:" + returnTypeName);
  輸出結果
  類(lèi)名:org.itstack.demo.javassist.ApiTest
方法:strToInt
類(lèi)型:非靜態(tài)方法
描述:(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Integer;
入參[名稱(chēng)]:str01,str02
入參[類(lèi)型]:java.lang.String,java.lang.String
出參[類(lèi)型]:java.lang.Integer
  以上,輸出信息為監控方法做準備。從上面可以記錄方法的基本描述和輸入參數的數量。尤其是入參的個(gè)數,因為后面需要用到$1來(lái)獲取沒(méi)有給入參的值。
  2. 方法字節碼檢測
  需要通過(guò)字節碼檢測來(lái)更改的原創(chuàng )方法;
  public class ApiTest {
public Integer strToInt(String str01, String str02) {
return Integer.parseInt(str01);
}
}
  2.1 先標記基礎屬性
  在監控的情況下,不可能將每次調用的所有方法信息都匯總輸出。這不僅僅是性能問(wèn)題,這些都是固定信息,不需要每次方法執行都輸出。
  這很好!然后在編譯方法時(shí),會(huì )為每個(gè)方法生成一個(gè)唯一的ID,并將方法的固定信息與ID關(guān)聯(lián)起來(lái)。也可以通過(guò)ID將監控數據傳遞到外部。
  // 方法:生成方法唯一標識ID
int idx = Monitor.generateMethodId(clazzName, methodName, parameterNameList, parameterTypeList, returnTypeName);
  生成ID的過(guò)程
  public static final int MAX_NUM = 1024 * 32;
private final static AtomicInteger index = new AtomicInteger(0);
private final static AtomicReferenceArray methodTagArr = new AtomicReferenceArray(MAX_NUM);
public static int generateMethodId(String clazzName, String methodName, List parameterNameList, List parameterTypeList, String returnType) {
MethodDescription methodDescription = new MethodDescription();
methodDescription.setClazzName(clazzName);
methodDescription.setMethodName(methodName);
methodDescription.setParameterNameList(parameterNameList);
methodDescription.setParameterTypeList(parameterTypeList);
methodDescription.setReturnType(returnType);
int methodId = index.getAndIncrement();
if (methodId > MAX_NUM) return -1;
methodTagArr.set(methodId, methodDescription);
return methodId;
}
  2.2 字節碼檢測增加入口方法時(shí)間
  // 定義屬性
ctMethod.addLocalVariable("startNanos", CtClass.longType);
// 方法前加強
ctMethod.insertBefore("{ startNanos = System.nanoTime(); }");
  final類(lèi)類(lèi)方法
  public class ApiTest {
public Integer strToInt(String str01, String str02) {
long startNanos = System.nanoTime();
return Integer.parseInt(str01);
}
}
  2.3 字節碼檢測添加輸入和輸出
  // 定義屬性
ctMethod.addLocalVariable("parameterValues", pool.get(Object[].class.getName()));
// 方法前加強
ctMethod.insertBefore("{ parameterValues = new Object[]{" + parameters.toString() + "}; }");
  final類(lèi)類(lèi)方法
  public Integer strToInt(String str01, String str02) {
Object[] var10000 = new Object[]{str01, str02};
long startNanos = System.nanoTime();
return Integer.parseInt(str01);
}
  2.4 定義監控方法
  因為我們需要向外部輸出監控信息。然后我們在這里定義一個(gè)靜態(tài)方法,讓字節碼增強的方法調用,并輸出監控信息。
  public static void point(final int methodId, final long startNanos, Object[] parameterValues, Object returnValues) {
MethodDescription method = methodTagArr.get(methodId);
System.out.println("監控 - Begin");
System.out.println("方法:" + method.getClazzName() + "." + method.getMethodName());
System.out.println("入參:" + JSON.toJSONString(method.getParameterNameList()) + " 入參[類(lèi)型]:" + JSON.toJSONString(method.getParameterTypeList()) + " 入數[值]:" + JSON.toJSONString(parameterValues));
System.out.println("出參:" + method.getReturnType() + " 出參[值]:" + JSON.toJSONString(returnValues));
System.out.println("耗時(shí):" + (System.nanoTime() - startNanos) / 1000000 + "(s)");
System.out.println("監控 - End\r\n");
}
public static void point(final int methodId, Throwable throwable) {
MethodDescription method = methodTagArr.get(methodId);
System.out.println("監控 - Begin");
System.out.println("方法:" + method.getClazzName() + "." + method.getMethodName());
System.out.println("異常:" + throwable.getMessage());
System.out.println("監控 - End\r\n");
}
  2.5 字節碼檢測調用監控方法
  // 方法后加強
ctMethod.insertAfter("{ org.itstack.demo.javassist.Monitor.point(" + idx + ", startNanos, parameterValues, $_);}", false); // 如果返回類(lèi)型非對象類(lèi)型,$_ 需要進(jìn)行類(lèi)型轉換
  final類(lèi)類(lèi)方法
  public Integer strToInt(String str01, String str02) {
Object[] parameterValues = new Object[]{str01, str02};
long startNanos = System.nanoTime();
Integer var7 = Integer.parseInt(str01);
Monitor.point(0, startNanos, parameterValues, var7);
return var7;
}
  2.6 字節碼檢測將 TryCatch 添加到方法中
  以上instrumentation內容,如果只是正常調用,是沒(méi)有問(wèn)題的。但是如果方法拋出異常,那么此時(shí)就無(wú)法采集到監控信息。所以你還需要將 TryCatch 添加到方法中。
  // 方法;添加TryCatch
ctMethod.addCatch("{ org.itstack.demo.javassist.Monitor.point(" + idx + ", $e); throw $e; }", ClassPool.getDefault().get("java.lang.Exception")); // 添加異常捕獲
  final類(lèi)類(lèi)方法
  public Integer strToInt(String str01, String str02) {
try {
Object[] parameterValues = new Object[]{str01, str02};
long startNanos = System.nanoTime();
Integer var7 = Integer.parseInt(str01);
Monitor.point(0, startNanos, parameterValues, var7);
return var7;
} catch (Exception var9) {
Monitor.point(0, var9);
throw var9;
}
}
  四、測試結果
  下一步是執行我們的調用來(lái)測試修改后的方法字節碼。通過(guò)不同的輸入參數驗證監測結果;
  // 測試調用
byte[] bytes = ctClass.toBytecode();
Class clazzNew = new GenerateClazzMethod().defineClass("org.itstack.demo.javassist.ApiTest", bytes, 0, bytes.length);
// 反射獲取 main 方法
Method method = clazzNew.getMethod("strToInt", String.class, String.class);
Object obj_01 = method.invoke(clazzNew.newInstance(), "1", "2");
System.out.println("正確入參:" + obj_01);
Object obj_02 = method.invoke(clazzNew.newInstance(), "a", "b");
System.out.println("異常入參:" + obj_02);
  測試結果
  監控 - Begin
方法:org.itstack.demo.javassist.ApiTest.strToInt
入參:["str01","str02"] 入參[類(lèi)型]:["java.lang.String","java.lang.String"] 入數[值]:["1","2"]
出參:java.lang.Integer 出參[值]:1
耗時(shí):63(s)
監控 - End
正確入參:1
監控 - Begin
方法:org.itstack.demo.javassist.ApiTest.strToInt
異常:For input string: "a"
監控 - End
  五、總結 查看全部

  文章采集調用(
開(kāi)發(fā)環(huán)境JDK1.8.0javassist本章本章GA本章涉及源碼的開(kāi)發(fā))
  
  一、前言
  字節碼編程插樁技術(shù)常結合Javaagent技術(shù)用于系統的非侵入式監控,可以替代方法中的硬編碼操作。例如,您需要監控一個(gè)方法,包括;方法信息、執行時(shí)間、輸入輸出參數、執行鏈接、異常。那么就非常適合用這樣的技術(shù)手段進(jìn)行加工。
  為了體現這部分的核心內容,本文將只使用Javassist技術(shù)對一段方法字節碼進(jìn)行instrument,最后輸出該方法的執行信息,如下;
  Method - 后續字節碼增強操作的測試方法
  public Integer strToInt(String str01, String str02) {
return Integer.parseInt(str01);
}
  監控 - 方法的字節碼增強后,輸出監控信息
  監控 - Begin
方法:org.itstack.demo.javassist.ApiTest.strToInt
入參:["str01","str02"] 入參[類(lèi)型]:["java.lang.String","java.lang.String"] 入數[值]:["1","2"]
出參:java.lang.Integer 出參[值]:1
耗時(shí):59(s)
監控 - End
  有了這樣的監控方案,我們基本上可以輸出方法執行過(guò)程中的所有信息。然后通過(guò)后期的改進(jìn),將監控信息顯示在界面上,并實(shí)時(shí)發(fā)出警報。不僅提高了系統的監控質(zhì)量,也便于研發(fā)排查和定位問(wèn)題。
  這很好!然后我們一步步開(kāi)始使用javassist進(jìn)行字節碼插樁,就達到了我們的監控效果。
  二、開(kāi)發(fā)環(huán)境JDK 1.8.0javassist 3.12.1.GA本章涉及的源碼為:itstack-demo-bytecode -1-04,可以關(guān)注公眾號:bugstack 蟲(chóng)洞棧,回復源碼下載即可。您將獲得下載鏈接列表。打開(kāi)后第十七期“因為我有很多開(kāi)源代碼”,記得給個(gè)Star!三、技術(shù)實(shí)現1. 獲取方法的基本信息1.1 獲取類(lèi)
  ClassPool pool = ClassPool.getDefault();
// 獲取類(lèi)
CtClass ctClass = pool.get(org.itstack.demo.javassist.ApiTest.class.getName());
ctClass.replaceClassName("ApiTest", "ApiTest02");
String clazzName = ctClass.getName();
  通過(guò)類(lèi)名獲取類(lèi)信息,這里可以替換類(lèi)名。它還包括一些其他操作來(lái)獲取類(lèi)中的屬性,例如;ctClass.getSimpleName()、ctClass.getAnnotations() 等等。
  1.2 如何獲得
  CtMethod ctMethod = ctClass.getDeclaredMethod("strToInt");
String methodName = ctMethod.getName();
  通過(guò)getDeclaredMethod獲取方法的CtMethod的內容。之后,您可以獲取方法名稱(chēng)等信息。
  1.3 方法信息
  MethodInfo methodInfo = ctMethod.getMethodInfo();
  MethodInfo 收錄方法信息;名稱(chēng)、類(lèi)型等
  1.4 種方法類(lèi)型
  boolean isStatic = (methodInfo.getAccessFlags() & AccessFlag.STATIC) != 0;
  通過(guò)methodInfo.getAccessFlags()獲取方法的標識符,然后使用AND運算AccessFlag.STATIC判斷該方法是否為靜態(tài)方法。因為靜態(tài)方法會(huì )影響后續參數名的獲取,所以靜態(tài)方法的第一個(gè)參數就是this,需要排除。
  1.5 方法:輸入參數信息{name and type}
  CodeAttribute codeAttribute = methodInfo.getCodeAttribute();
LocalVariableAttribute attr = (LocalVariableAttribute) codeAttribute.getAttribute(LocalVariableAttribute.tag);
CtClass[] parameterTypes = ctMethod.getParameterTypes();
  1.6 方法;參數信息
  CtClass returnType = ctMethod.getReturnType();
String returnTypeName = returnType.getName();
  對于方法的參數信息,只需要獲取參數類(lèi)型即可。
  1.7 輸出所有獲取的信息
  System.out.println("類(lèi)名:" + clazzName);
System.out.println("方法:" + methodName);
System.out.println("類(lèi)型:" + (isStatic ? "靜態(tài)方法" : "非靜態(tài)方法"));
System.out.println("描述:" + methodInfo.getDescriptor());
System.out.println("入參[名稱(chēng)]:" + attr.variableName(1) + "," + attr.variableName(2));
System.out.println("入參[類(lèi)型]:" + parameterTypes[0].getName() + "," + parameterTypes[1].getName());
System.out.println("出參[類(lèi)型]:" + returnTypeName);
  輸出結果
  類(lèi)名:org.itstack.demo.javassist.ApiTest
方法:strToInt
類(lèi)型:非靜態(tài)方法
描述:(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Integer;
入參[名稱(chēng)]:str01,str02
入參[類(lèi)型]:java.lang.String,java.lang.String
出參[類(lèi)型]:java.lang.Integer
  以上,輸出信息為監控方法做準備。從上面可以記錄方法的基本描述和輸入參數的數量。尤其是入參的個(gè)數,因為后面需要用到$1來(lái)獲取沒(méi)有給入參的值。
  2. 方法字節碼檢測
  需要通過(guò)字節碼檢測來(lái)更改的原創(chuàng )方法;
  public class ApiTest {
public Integer strToInt(String str01, String str02) {
return Integer.parseInt(str01);
}
}
  2.1 先標記基礎屬性
  在監控的情況下,不可能將每次調用的所有方法信息都匯總輸出。這不僅僅是性能問(wèn)題,這些都是固定信息,不需要每次方法執行都輸出。
  這很好!然后在編譯方法時(shí),會(huì )為每個(gè)方法生成一個(gè)唯一的ID,并將方法的固定信息與ID關(guān)聯(lián)起來(lái)。也可以通過(guò)ID將監控數據傳遞到外部。
  // 方法:生成方法唯一標識ID
int idx = Monitor.generateMethodId(clazzName, methodName, parameterNameList, parameterTypeList, returnTypeName);
  生成ID的過(guò)程
  public static final int MAX_NUM = 1024 * 32;
private final static AtomicInteger index = new AtomicInteger(0);
private final static AtomicReferenceArray methodTagArr = new AtomicReferenceArray(MAX_NUM);
public static int generateMethodId(String clazzName, String methodName, List parameterNameList, List parameterTypeList, String returnType) {
MethodDescription methodDescription = new MethodDescription();
methodDescription.setClazzName(clazzName);
methodDescription.setMethodName(methodName);
methodDescription.setParameterNameList(parameterNameList);
methodDescription.setParameterTypeList(parameterTypeList);
methodDescription.setReturnType(returnType);
int methodId = index.getAndIncrement();
if (methodId > MAX_NUM) return -1;
methodTagArr.set(methodId, methodDescription);
return methodId;
}
  2.2 字節碼檢測增加入口方法時(shí)間
  // 定義屬性
ctMethod.addLocalVariable("startNanos", CtClass.longType);
// 方法前加強
ctMethod.insertBefore("{ startNanos = System.nanoTime(); }");
  final類(lèi)類(lèi)方法
  public class ApiTest {
public Integer strToInt(String str01, String str02) {
long startNanos = System.nanoTime();
return Integer.parseInt(str01);
}
}
  2.3 字節碼檢測添加輸入和輸出
  // 定義屬性
ctMethod.addLocalVariable("parameterValues", pool.get(Object[].class.getName()));
// 方法前加強
ctMethod.insertBefore("{ parameterValues = new Object[]{" + parameters.toString() + "}; }");
  final類(lèi)類(lèi)方法
  public Integer strToInt(String str01, String str02) {
Object[] var10000 = new Object[]{str01, str02};
long startNanos = System.nanoTime();
return Integer.parseInt(str01);
}
  2.4 定義監控方法
  因為我們需要向外部輸出監控信息。然后我們在這里定義一個(gè)靜態(tài)方法,讓字節碼增強的方法調用,并輸出監控信息。
  public static void point(final int methodId, final long startNanos, Object[] parameterValues, Object returnValues) {
MethodDescription method = methodTagArr.get(methodId);
System.out.println("監控 - Begin");
System.out.println("方法:" + method.getClazzName() + "." + method.getMethodName());
System.out.println("入參:" + JSON.toJSONString(method.getParameterNameList()) + " 入參[類(lèi)型]:" + JSON.toJSONString(method.getParameterTypeList()) + " 入數[值]:" + JSON.toJSONString(parameterValues));
System.out.println("出參:" + method.getReturnType() + " 出參[值]:" + JSON.toJSONString(returnValues));
System.out.println("耗時(shí):" + (System.nanoTime() - startNanos) / 1000000 + "(s)");
System.out.println("監控 - End\r\n");
}
public static void point(final int methodId, Throwable throwable) {
MethodDescription method = methodTagArr.get(methodId);
System.out.println("監控 - Begin");
System.out.println("方法:" + method.getClazzName() + "." + method.getMethodName());
System.out.println("異常:" + throwable.getMessage());
System.out.println("監控 - End\r\n");
}
  2.5 字節碼檢測調用監控方法
  // 方法后加強
ctMethod.insertAfter("{ org.itstack.demo.javassist.Monitor.point(" + idx + ", startNanos, parameterValues, $_);}", false); // 如果返回類(lèi)型非對象類(lèi)型,$_ 需要進(jìn)行類(lèi)型轉換
  final類(lèi)類(lèi)方法
  public Integer strToInt(String str01, String str02) {
Object[] parameterValues = new Object[]{str01, str02};
long startNanos = System.nanoTime();
Integer var7 = Integer.parseInt(str01);
Monitor.point(0, startNanos, parameterValues, var7);
return var7;
}
  2.6 字節碼檢測將 TryCatch 添加到方法中
  以上instrumentation內容,如果只是正常調用,是沒(méi)有問(wèn)題的。但是如果方法拋出異常,那么此時(shí)就無(wú)法采集到監控信息。所以你還需要將 TryCatch 添加到方法中。
  // 方法;添加TryCatch
ctMethod.addCatch("{ org.itstack.demo.javassist.Monitor.point(" + idx + ", $e); throw $e; }", ClassPool.getDefault().get("java.lang.Exception")); // 添加異常捕獲
  final類(lèi)類(lèi)方法
  public Integer strToInt(String str01, String str02) {
try {
Object[] parameterValues = new Object[]{str01, str02};
long startNanos = System.nanoTime();
Integer var7 = Integer.parseInt(str01);
Monitor.point(0, startNanos, parameterValues, var7);
return var7;
} catch (Exception var9) {
Monitor.point(0, var9);
throw var9;
}
}
  四、測試結果
  下一步是執行我們的調用來(lái)測試修改后的方法字節碼。通過(guò)不同的輸入參數驗證監測結果;
  // 測試調用
byte[] bytes = ctClass.toBytecode();
Class clazzNew = new GenerateClazzMethod().defineClass("org.itstack.demo.javassist.ApiTest", bytes, 0, bytes.length);
// 反射獲取 main 方法
Method method = clazzNew.getMethod("strToInt", String.class, String.class);
Object obj_01 = method.invoke(clazzNew.newInstance(), "1", "2");
System.out.println("正確入參:" + obj_01);
Object obj_02 = method.invoke(clazzNew.newInstance(), "a", "b");
System.out.println("異常入參:" + obj_02);
  測試結果
  監控 - Begin
方法:org.itstack.demo.javassist.ApiTest.strToInt
入參:["str01","str02"] 入參[類(lèi)型]:["java.lang.String","java.lang.String"] 入數[值]:["1","2"]
出參:java.lang.Integer 出參[值]:1
耗時(shí):63(s)
監控 - End
正確入參:1
監控 - Begin
方法:org.itstack.demo.javassist.ApiTest.strToInt
異常:For input string: "a"
監控 - End
  五、總結

文章采集調用(優(yōu)采云采集+偽原創(chuàng )錯誤博客分享《《》)

采集交流 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 138 次瀏覽 ? 2022-04-13 05:18 ? 來(lái)自相關(guān)話(huà)題

  文章采集調用(優(yōu)采云采集+偽原創(chuàng )錯誤博客分享《《》)
  優(yōu)采云 是一個(gè)非常有用的文章采集 工具,但它也是一個(gè)很多人不知道的文章 構建工具。優(yōu)采云采集+偽原創(chuàng ) 方法已經(jīng)流行了這么多年,仍然被大量的人使用,構建 原創(chuàng )文章 將使網(wǎng)站 改變更好的質(zhì)量。今天,bug 博客( )分享了“優(yōu)采云采集如何量產(chǎn)原創(chuàng )文章”。我希望能有所幫助。
  優(yōu)采云構建原創(chuàng )文章
  一、優(yōu)采云采集+偽原創(chuàng )
  報錯博客先講優(yōu)采云采集偽原創(chuàng )的操作方法。查找更好的信息網(wǎng)站采集一些較新的文章、采集有互聯(lián)網(wǎng)熱詞,如百度搜索熱點(diǎn)、抖音熱點(diǎn)、微信博熱搜和很快。
  標題不要重復,不建議直接偽原創(chuàng )標題。最好手動(dòng)編輯標題。內容 偽原創(chuàng ) 應該是可讀的。如果不可讀,不建議使用那種工具,因為這個(gè)內容已經(jīng)發(fā)了很久了,網(wǎng)站活不了多久了。
  優(yōu)采云采集+偽原創(chuàng )的形式確實(shí)可以創(chuàng )作很多內容,但是也應該考慮在網(wǎng)站中發(fā)布一些原創(chuàng )文章提高百度信心,讓您事半功倍。
  二、優(yōu)采云構建原創(chuàng )文章
  與其 優(yōu)采云 構造 原創(chuàng )文章 不如調用內容,然后使用 文章 正文內容格式調用那些單詞和句子。如何將這些單詞和句子很好地呈現給用戶(hù)和搜索引擎,不僅具有一定的可讀性,而且具有看似實(shí)用的功能。這是錯誤博客的示例。當 愛(ài)站 網(wǎng)絡(luò )對 網(wǎng)站 進(jìn)行數據查詢(xún)時(shí),該頁(yè)面是一個(gè)類(lèi)似于 原創(chuàng )文章 的新頁(yè)面,通過(guò)調用各種數據形成。頁(yè)面,這樣的頁(yè)面有很好的排名。當這種頁(yè)面出現在搜索引擎中時(shí),很多人會(huì )選擇點(diǎn)擊,而且可能會(huì )停留很長(cháng)時(shí)間。這是一個(gè)成功的案例。
  當然,錯誤博客并沒(méi)有那么有能力做出這樣一種形式的頁(yè)面來(lái)調用各種數據,但是我們可以根據自己的能力來(lái)構建這樣一個(gè)原創(chuàng )頁(yè)面,這樣大量的內容頁(yè)面就會(huì )不被我們使用。搜索引擎的罷工也可能會(huì )受到鼓勵,畢竟這個(gè)頁(yè)面非常實(shí)用。 查看全部

  文章采集調用(優(yōu)采云采集+偽原創(chuàng )錯誤博客分享《《》)
  優(yōu)采云 是一個(gè)非常有用的文章采集 工具,但它也是一個(gè)很多人不知道的文章 構建工具。優(yōu)采云采集+偽原創(chuàng ) 方法已經(jīng)流行了這么多年,仍然被大量的人使用,構建 原創(chuàng )文章 將使網(wǎng)站 改變更好的質(zhì)量。今天,bug 博客( )分享了“優(yōu)采云采集如何量產(chǎn)原創(chuàng )文章”。我希望能有所幫助。
  優(yōu)采云構建原創(chuàng )文章
  一、優(yōu)采云采集+偽原創(chuàng )
  報錯博客先講優(yōu)采云采集偽原創(chuàng )的操作方法。查找更好的信息網(wǎng)站采集一些較新的文章、采集有互聯(lián)網(wǎng)熱詞,如百度搜索熱點(diǎn)、抖音熱點(diǎn)、微信博熱搜和很快。
  標題不要重復,不建議直接偽原創(chuàng )標題。最好手動(dòng)編輯標題。內容 偽原創(chuàng ) 應該是可讀的。如果不可讀,不建議使用那種工具,因為這個(gè)內容已經(jīng)發(fā)了很久了,網(wǎng)站活不了多久了。
  優(yōu)采云采集+偽原創(chuàng )的形式確實(shí)可以創(chuàng )作很多內容,但是也應該考慮在網(wǎng)站中發(fā)布一些原創(chuàng )文章提高百度信心,讓您事半功倍。
  二、優(yōu)采云構建原創(chuàng )文章
  與其 優(yōu)采云 構造 原創(chuàng )文章 不如調用內容,然后使用 文章 正文內容格式調用那些單詞和句子。如何將這些單詞和句子很好地呈現給用戶(hù)和搜索引擎,不僅具有一定的可讀性,而且具有看似實(shí)用的功能。這是錯誤博客的示例。當 愛(ài)站 網(wǎng)絡(luò )對 網(wǎng)站 進(jìn)行數據查詢(xún)時(shí),該頁(yè)面是一個(gè)類(lèi)似于 原創(chuàng )文章 的新頁(yè)面,通過(guò)調用各種數據形成。頁(yè)面,這樣的頁(yè)面有很好的排名。當這種頁(yè)面出現在搜索引擎中時(shí),很多人會(huì )選擇點(diǎn)擊,而且可能會(huì )停留很長(cháng)時(shí)間。這是一個(gè)成功的案例。
  當然,錯誤博客并沒(méi)有那么有能力做出這樣一種形式的頁(yè)面來(lái)調用各種數據,但是我們可以根據自己的能力來(lái)構建這樣一個(gè)原創(chuàng )頁(yè)面,這樣大量的內容頁(yè)面就會(huì )不被我們使用。搜索引擎的罷工也可能會(huì )受到鼓勵,畢竟這個(gè)頁(yè)面非常實(shí)用。

文章采集調用(R語(yǔ)言爬蟲(chóng)格式的json格式,尋找新的方法!)

采集交流 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 143 次瀏覽 ? 2022-04-12 19:35 ? 來(lái)自相關(guān)話(huà)題

  文章采集調用(R語(yǔ)言爬蟲(chóng)格式的json格式,尋找新的方法!)
  ==========背景===================
  最近一直在用R語(yǔ)言爬,但是有些網(wǎng)站是動(dòng)態(tài)json格式的。每次都找到重定向的 URL 很麻煩。因此,我正在尋找一種新方法,構建一個(gè)瀏覽器,在瀏覽器中查找 URL。于是出現了以下問(wèn)題:
  ==========執行步驟分割線(xiàn)============
  1、cmd enable java -jar selenium-server-standalone-2.53.0.jar //啟動(dòng)selenium
  2、R 控制臺
  > library("Rwebdriver", lib.loc="C:/Program Files/R/R-3.2.3/library")
  加載所需的包:RCurl
  加載所需的包:bitops
  加載所需包:RJSONIO
  > library("XML", lib.loc="\\\\CNDOUW0000/Users/CNLeeWi/R/win-library/3.2")
  > start_session(root = "" ,browser = "firefox")
  函數錯誤(類(lèi)型、msg、asError = TRUE):
  無(wú)法連接到 localhost 端口 80:連接被拒絕
  ==========相關(guān)信息鏈接================== 查看全部

  文章采集調用(R語(yǔ)言爬蟲(chóng)格式的json格式,尋找新的方法!)
  ==========背景===================
  最近一直在用R語(yǔ)言爬,但是有些網(wǎng)站是動(dòng)態(tài)json格式的。每次都找到重定向的 URL 很麻煩。因此,我正在尋找一種新方法,構建一個(gè)瀏覽器,在瀏覽器中查找 URL。于是出現了以下問(wèn)題:
  ==========執行步驟分割線(xiàn)============
  1、cmd enable java -jar selenium-server-standalone-2.53.0.jar //啟動(dòng)selenium
  2、R 控制臺
  > library("Rwebdriver", lib.loc="C:/Program Files/R/R-3.2.3/library")
  加載所需的包:RCurl
  加載所需的包:bitops
  加載所需包:RJSONIO
  > library("XML", lib.loc="\\\\CNDOUW0000/Users/CNLeeWi/R/win-library/3.2")
  > start_session(root = "" ,browser = "firefox")
  函數錯誤(類(lèi)型、msg、asError = TRUE):
  無(wú)法連接到 localhost 端口 80:連接被拒絕
  ==========相關(guān)信息鏈接==================

文章采集調用(天弘基金(余額寶)移動(dòng)平臺首席架構師負責人)

采集交流 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 127 次瀏覽 ? 2022-04-12 17:31 ? 來(lái)自相關(guān)話(huà)題

  文章采集調用(天弘基金(余額寶)移動(dòng)平臺首席架構師負責人)
  近年來(lái),APM進(jìn)入了快速發(fā)展的快車(chē)道。作為APM的核心功能,分布式環(huán)境下的自動(dòng)應用發(fā)現和動(dòng)態(tài)調用鏈路分析也被廣泛應用于A(yíng)PM的推廣。一些不足暴露出來(lái):完全基于運行狀態(tài)的分析模式?jīng)Q定了只能獲取與實(shí)際調用的邏輯鏈接,大量未被掩埋或未被觸發(fā)的調用邏輯成為無(wú)法觸及的“失落的世界” . 撞。找到這部分“失落的世界”對于我們了解分布式環(huán)境中應用程序的全貌非常重要。天鴻基金移動(dòng)平臺團隊在這方面進(jìn)行了一些創(chuàng )新探索。我們跳出了傳統APM的慣性思維,掃描分析海量代碼中的調用關(guān)系,得到分布式環(huán)境下“前中后”站的完整調用鏈,并在此基礎上疊加動(dòng)態(tài)調用鏈,構建精細化APM監控。通過(guò)這個(gè)話(huà)題,我將結合我們的實(shí)踐,詳細介紹“靜態(tài)調用鏈路發(fā)現”的技術(shù)和手段,并探討如何在運維和開(kāi)發(fā)場(chǎng)景中將其與現有的APM能力相結合。--&gt;觀(guān)眾受益:1、了解分布式環(huán)境下APM的“優(yōu)”與“差”。2、了解構建“靜態(tài)呼叫鏈路發(fā)現”能力的技術(shù)和手段。3、 學(xué)習如何用創(chuàng )新思維拓展APM的應用場(chǎng)景。--&gt; 個(gè)人介紹:天弘基金(月寶)移動(dòng)平臺首席架構師李鑫,負責移動(dòng)平臺整體技術(shù)架構設計。曾任當當網(wǎng)架構師,負責電商后端運營(yíng)產(chǎn)品平臺整體技術(shù)架構及研發(fā)團隊管理;華為云計算專(zhuān)家,主導華為軟件各類(lèi)云計算產(chǎn)品和服務(wù)的設計、規劃和建設。個(gè)人技術(shù)涉及大規模分布式應用與治理、中間件云化與服務(wù)化(PaaS)、APM監控、基礎開(kāi)發(fā)平臺等領(lǐng)域, 查看全部

  文章采集調用(天弘基金(余額寶)移動(dòng)平臺首席架構師負責人)
  近年來(lái),APM進(jìn)入了快速發(fā)展的快車(chē)道。作為APM的核心功能,分布式環(huán)境下的自動(dòng)應用發(fā)現和動(dòng)態(tài)調用鏈路分析也被廣泛應用于A(yíng)PM的推廣。一些不足暴露出來(lái):完全基于運行狀態(tài)的分析模式?jīng)Q定了只能獲取與實(shí)際調用的邏輯鏈接,大量未被掩埋或未被觸發(fā)的調用邏輯成為無(wú)法觸及的“失落的世界” . 撞。找到這部分“失落的世界”對于我們了解分布式環(huán)境中應用程序的全貌非常重要。天鴻基金移動(dòng)平臺團隊在這方面進(jìn)行了一些創(chuàng )新探索。我們跳出了傳統APM的慣性思維,掃描分析海量代碼中的調用關(guān)系,得到分布式環(huán)境下“前中后”站的完整調用鏈,并在此基礎上疊加動(dòng)態(tài)調用鏈,構建精細化APM監控。通過(guò)這個(gè)話(huà)題,我將結合我們的實(shí)踐,詳細介紹“靜態(tài)調用鏈路發(fā)現”的技術(shù)和手段,并探討如何在運維和開(kāi)發(fā)場(chǎng)景中將其與現有的APM能力相結合。--&gt;觀(guān)眾受益:1、了解分布式環(huán)境下APM的“優(yōu)”與“差”。2、了解構建“靜態(tài)呼叫鏈路發(fā)現”能力的技術(shù)和手段。3、 學(xué)習如何用創(chuàng )新思維拓展APM的應用場(chǎng)景。--&gt; 個(gè)人介紹:天弘基金(月寶)移動(dòng)平臺首席架構師李鑫,負責移動(dòng)平臺整體技術(shù)架構設計。曾任當當網(wǎng)架構師,負責電商后端運營(yíng)產(chǎn)品平臺整體技術(shù)架構及研發(fā)團隊管理;華為云計算專(zhuān)家,主導華為軟件各類(lèi)云計算產(chǎn)品和服務(wù)的設計、規劃和建設。個(gè)人技術(shù)涉及大規模分布式應用與治理、中間件云化與服務(wù)化(PaaS)、APM監控、基礎開(kāi)發(fā)平臺等領(lǐng)域,

文章采集調用(一個(gè)企業(yè)網(wǎng)站被百度降權了怎么辦?(圖))

采集交流 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 134 次瀏覽 ? 2022-04-12 06:32 ? 來(lái)自相關(guān)話(huà)題

  文章采集調用(一個(gè)企業(yè)網(wǎng)站被百度降權了怎么辦?(圖))
  去年年底,一位客戶(hù)要求我幫助創(chuàng )建一家公司網(wǎng)站??紤]到 網(wǎng)站 將來(lái)會(huì )推廣搜索引擎,網(wǎng)站 在 SEO 中必須是搜索引擎友好的。最后我選擇了DeDecms,它可以在URL、PageTitle、TextBlock、LinkBlock、Auto Sitemap、Related Article中做早期的SEO布局。所以在欄目規劃、版面設計、模板制作階段,我將各種SEO元素充分融入到整個(gè)制作階段,希望網(wǎng)站上線(xiàn)后,能夠快速積累搜索排名權重。尤其是在模板代碼編寫(xiě)方面,可以有效控制鏈接輸出和導入,盡可能提高內部鏈接的相關(guān)性和關(guān)鍵詞的匹配位置,去除無(wú)用的網(wǎng)頁(yè)噪音信息,
  果然,網(wǎng)站正式發(fā)布后,網(wǎng)站收錄的占比迅速達到70%,大部分產(chǎn)品終端頁(yè)面為收錄,部分信息頁(yè)面為收錄 ,更重要的是:行業(yè)關(guān)鍵詞排名和產(chǎn)品關(guān)鍵詞排名進(jìn)步很快;整個(gè)網(wǎng)站在SEO運營(yíng)中呈現良性發(fā)展態(tài)勢??蛻?hù)端開(kāi)始接管網(wǎng)站并正常更新站點(diǎn)內容,按照設定的時(shí)間表,一切應該都進(jìn)行得很順利。
  不過(guò)最近網(wǎng)站SEO的表現開(kāi)始下滑,網(wǎng)頁(yè)數量收錄首當其沖。百度統計后臺顯示的頁(yè)面索引與搜索框中site命令返回的結果數量有顯著(zhù)差異。site 命令顯示 Only 2 pages are 收錄,都是首頁(yè),首頁(yè)有 www 和沒(méi)有 www 的兩個(gè)版本。另外,信息正常更新后,百度索引很快,短時(shí)間內可以通過(guò)site命令返回結果,但過(guò)了一會(huì )兒發(fā)現收錄無(wú)效?;谝陨锨闆r,我認為網(wǎng)站已經(jīng)被百度降級了。
  為了找到問(wèn)題所在,我研究了各種因素,發(fā)現:
 ?。?)除了正常更新網(wǎng)站的內容外,企業(yè)端也在積極運營(yíng)外鏈,建外鏈是好事,但是用錯了方式參與資源站的鏈輪;
 ?。?)網(wǎng)上有相同模板、相同內容、不同品牌的仿站,而百度上的仿站收錄也只有首頁(yè),“驚人的相似” ”給客戶(hù)網(wǎng)站。
  1、關(guān)于鏈輪問(wèn)題,幸好我及時(shí)發(fā)現并制止了這種行為。由于參與sprocket的產(chǎn)品頁(yè)面只有幾個(gè),時(shí)間不長(cháng),應該不會(huì )有這么大的影響,更何況自己的資源站。.
  2、關(guān)于重復站點(diǎn),非常少見(jiàn)。大多數人會(huì )自覺(jué)地在網(wǎng)站內??容或組織形式上形成差異;而如果客戶(hù)網(wǎng)站有這樣的SEO癥狀,恐怕關(guān)鍵就在于仿網(wǎng)站,當我看到仿網(wǎng)站的時(shí)候,我完全無(wú)語(yǔ)了。除了公司的品牌名稱(chēng)不同,網(wǎng)站我都太了解了;本來(lái)想吐槽的,但回頭看,現在網(wǎng)絡(luò )不流行了。是不是到處都有抄襲的趨勢?或許習慣了就好,但我不能忍受的是模板100%模仿,數據完整采集沒(méi)事,拜托,你敢不敢放是99 % 相同的網(wǎng)站作為一個(gè)整體發(fā)布?你TMD搞SEO,不知道類(lèi)似網(wǎng)站!你的TMD模仿站也可以模仿我過(guò)去寫(xiě)的自動(dòng)更新的網(wǎng)站地圖文件sitemap.php!做SEO傷不起啊。
  吐槽回吐槽,問(wèn)題還是要解決,采用了幾個(gè)方法:
  1、調整模板數據調用規則和新內容塊布局
  新的內容塊會(huì )使頁(yè)面主題關(guān)鍵詞更加分散,并調整數據調用規則,使仿站點(diǎn)的數據與自己頁(yè)面的數據不同,減少復制網(wǎng)站的負面影響@>搜索引擎優(yōu)化問(wèn)題。
  2、想辦法阻止內容采集
  DeDecms本身就有防止采集混淆字符串的功能,但是這種防止采集的方法對SEO來(lái)說(shuō)是非常不利的。您不希望搜索蜘蛛看到網(wǎng)頁(yè)中有許多隱藏的隱藏對象。文字,而這些文字會(huì )影響蜘蛛對信息塊主題的判斷,影響關(guān)鍵詞的排名。事實(shí)上,DeDecms并沒(méi)有根本的辦法來(lái)阻止采集,而且是一尺高。高一章,只要通過(guò)頁(yè)面發(fā)布你的信息,總能找到采集的方法;我根據網(wǎng)上搜集的資料采用了兩種方法,只能放最基本的采集。&gt;:
  (1)方法一:復制網(wǎng)頁(yè)正文內容時(shí)自動(dòng)添加版權信息
  JavaScript 代碼
  將上面的代碼放在文章頁(yè)面模板中文本末尾之后。這個(gè)方法我測試過(guò),只對IE瀏覽器有效,對火狐、傲游、谷歌瀏覽器無(wú)效。
  (2)方法二:使頁(yè)面代碼唯一
  一般別人采集時(shí),要獲取內容的起始碼和結束碼,而且必須是唯一的,所以填寫(xiě)的起始碼多為:
  . 這樣,我們在這個(gè)類(lèi)后面加上文章的ID值,改成這個(gè)
  ,其中{dede:field.id/}獲取dedecms中當前文章的ID值,那么每個(gè)生成的文章的ID值都不一樣,這里的起始代碼為也不同,所以其他人將無(wú)法采集,并且您一次只能選擇一件。
  當我們制作模板時(shí),在body標簽附近
  變成
  ,注意空格+{dede:field.id/},所以div的class沒(méi)有變,但是
  ,此代碼在每個(gè)文章的內容頁(yè)面中是唯一的,或者在html標簽中插入id={dede:field.id/},例如:
  并且,這里的{dede:field.id/}是在dedecms中獲取當前文章的ID值,這樣別人就無(wú)法采集了,只有一個(gè)可以一次采集。當然,其他人可以使用過(guò)濾規則來(lái)移除,但是如果我在所有類(lèi)中插入文檔ID,或者插入id=文檔ID。然后他只能采集整個(gè)頁(yè)面,然后過(guò)濾,使得采集更加復雜。
  缺點(diǎn):如果{dede:field.id/}插入的不夠多,其他人可以用過(guò)濾規則過(guò)濾掉。但是對于一些站群采集軟件來(lái)說(shuō),這個(gè)招數就足以阻止他們采集了!
  3、升級DeDecms到最新版本
  DeDecms老版本有漏洞,很容易被黑,要么嵌入各種廣告代碼,要么無(wú)緣無(wú)故添加太多隱藏鏈接,所以一定要升級到最新版本。
  上一篇:織夢(mèng)cms:錯誤的解決方法:check Snooping out of bounds
  下一步:設置dedecms標簽[field:global.autoindex/]的初始值 查看全部

  文章采集調用(一個(gè)企業(yè)網(wǎng)站被百度降權了怎么辦?(圖))
  去年年底,一位客戶(hù)要求我幫助創(chuàng )建一家公司網(wǎng)站??紤]到 網(wǎng)站 將來(lái)會(huì )推廣搜索引擎,網(wǎng)站 在 SEO 中必須是搜索引擎友好的。最后我選擇了DeDecms,它可以在URL、PageTitle、TextBlock、LinkBlock、Auto Sitemap、Related Article中做早期的SEO布局。所以在欄目規劃、版面設計、模板制作階段,我將各種SEO元素充分融入到整個(gè)制作階段,希望網(wǎng)站上線(xiàn)后,能夠快速積累搜索排名權重。尤其是在模板代碼編寫(xiě)方面,可以有效控制鏈接輸出和導入,盡可能提高內部鏈接的相關(guān)性和關(guān)鍵詞的匹配位置,去除無(wú)用的網(wǎng)頁(yè)噪音信息,
  果然,網(wǎng)站正式發(fā)布后,網(wǎng)站收錄的占比迅速達到70%,大部分產(chǎn)品終端頁(yè)面為收錄,部分信息頁(yè)面為收錄 ,更重要的是:行業(yè)關(guān)鍵詞排名和產(chǎn)品關(guān)鍵詞排名進(jìn)步很快;整個(gè)網(wǎng)站在SEO運營(yíng)中呈現良性發(fā)展態(tài)勢??蛻?hù)端開(kāi)始接管網(wǎng)站并正常更新站點(diǎn)內容,按照設定的時(shí)間表,一切應該都進(jìn)行得很順利。
  不過(guò)最近網(wǎng)站SEO的表現開(kāi)始下滑,網(wǎng)頁(yè)數量收錄首當其沖。百度統計后臺顯示的頁(yè)面索引與搜索框中site命令返回的結果數量有顯著(zhù)差異。site 命令顯示 Only 2 pages are 收錄,都是首頁(yè),首頁(yè)有 www 和沒(méi)有 www 的兩個(gè)版本。另外,信息正常更新后,百度索引很快,短時(shí)間內可以通過(guò)site命令返回結果,但過(guò)了一會(huì )兒發(fā)現收錄無(wú)效?;谝陨锨闆r,我認為網(wǎng)站已經(jīng)被百度降級了。
  為了找到問(wèn)題所在,我研究了各種因素,發(fā)現:
 ?。?)除了正常更新網(wǎng)站的內容外,企業(yè)端也在積極運營(yíng)外鏈,建外鏈是好事,但是用錯了方式參與資源站的鏈輪;
 ?。?)網(wǎng)上有相同模板、相同內容、不同品牌的仿站,而百度上的仿站收錄也只有首頁(yè),“驚人的相似” ”給客戶(hù)網(wǎng)站。
  1、關(guān)于鏈輪問(wèn)題,幸好我及時(shí)發(fā)現并制止了這種行為。由于參與sprocket的產(chǎn)品頁(yè)面只有幾個(gè),時(shí)間不長(cháng),應該不會(huì )有這么大的影響,更何況自己的資源站。.
  2、關(guān)于重復站點(diǎn),非常少見(jiàn)。大多數人會(huì )自覺(jué)地在網(wǎng)站內??容或組織形式上形成差異;而如果客戶(hù)網(wǎng)站有這樣的SEO癥狀,恐怕關(guān)鍵就在于仿網(wǎng)站,當我看到仿網(wǎng)站的時(shí)候,我完全無(wú)語(yǔ)了。除了公司的品牌名稱(chēng)不同,網(wǎng)站我都太了解了;本來(lái)想吐槽的,但回頭看,現在網(wǎng)絡(luò )不流行了。是不是到處都有抄襲的趨勢?或許習慣了就好,但我不能忍受的是模板100%模仿,數據完整采集沒(méi)事,拜托,你敢不敢放是99 % 相同的網(wǎng)站作為一個(gè)整體發(fā)布?你TMD搞SEO,不知道類(lèi)似網(wǎng)站!你的TMD模仿站也可以模仿我過(guò)去寫(xiě)的自動(dòng)更新的網(wǎng)站地圖文件sitemap.php!做SEO傷不起啊。
  吐槽回吐槽,問(wèn)題還是要解決,采用了幾個(gè)方法:
  1、調整模板數據調用規則和新內容塊布局
  新的內容塊會(huì )使頁(yè)面主題關(guān)鍵詞更加分散,并調整數據調用規則,使仿站點(diǎn)的數據與自己頁(yè)面的數據不同,減少復制網(wǎng)站的負面影響@>搜索引擎優(yōu)化問(wèn)題。
  2、想辦法阻止內容采集
  DeDecms本身就有防止采集混淆字符串的功能,但是這種防止采集的方法對SEO來(lái)說(shuō)是非常不利的。您不希望搜索蜘蛛看到網(wǎng)頁(yè)中有許多隱藏的隱藏對象。文字,而這些文字會(huì )影響蜘蛛對信息塊主題的判斷,影響關(guān)鍵詞的排名。事實(shí)上,DeDecms并沒(méi)有根本的辦法來(lái)阻止采集,而且是一尺高。高一章,只要通過(guò)頁(yè)面發(fā)布你的信息,總能找到采集的方法;我根據網(wǎng)上搜集的資料采用了兩種方法,只能放最基本的采集。&gt;:
  (1)方法一:復制網(wǎng)頁(yè)正文內容時(shí)自動(dòng)添加版權信息
  JavaScript 代碼
  將上面的代碼放在文章頁(yè)面模板中文本末尾之后。這個(gè)方法我測試過(guò),只對IE瀏覽器有效,對火狐、傲游、谷歌瀏覽器無(wú)效。
  (2)方法二:使頁(yè)面代碼唯一
  一般別人采集時(shí),要獲取內容的起始碼和結束碼,而且必須是唯一的,所以填寫(xiě)的起始碼多為:
  . 這樣,我們在這個(gè)類(lèi)后面加上文章的ID值,改成這個(gè)
  ,其中{dede:field.id/}獲取dedecms中當前文章的ID值,那么每個(gè)生成的文章的ID值都不一樣,這里的起始代碼為也不同,所以其他人將無(wú)法采集,并且您一次只能選擇一件。
  當我們制作模板時(shí),在body標簽附近
  變成
  ,注意空格+{dede:field.id/},所以div的class沒(méi)有變,但是
  ,此代碼在每個(gè)文章的內容頁(yè)面中是唯一的,或者在html標簽中插入id={dede:field.id/},例如:
  并且,這里的{dede:field.id/}是在dedecms中獲取當前文章的ID值,這樣別人就無(wú)法采集了,只有一個(gè)可以一次采集。當然,其他人可以使用過(guò)濾規則來(lái)移除,但是如果我在所有類(lèi)中插入文檔ID,或者插入id=文檔ID。然后他只能采集整個(gè)頁(yè)面,然后過(guò)濾,使得采集更加復雜。
  缺點(diǎn):如果{dede:field.id/}插入的不夠多,其他人可以用過(guò)濾規則過(guò)濾掉。但是對于一些站群采集軟件來(lái)說(shuō),這個(gè)招數就足以阻止他們采集了!
  3、升級DeDecms到最新版本
  DeDecms老版本有漏洞,很容易被黑,要么嵌入各種廣告代碼,要么無(wú)緣無(wú)故添加太多隱藏鏈接,所以一定要升級到最新版本。
  上一篇:織夢(mèng)cms:錯誤的解決方法:check Snooping out of bounds
  下一步:設置dedecms標簽[field:global.autoindex/]的初始值

文章采集調用(1.用python爬取代理批量采集實(shí)現方法:anyproxy+js)

采集交流 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 129 次瀏覽 ? 2022-04-11 13:02 ? 來(lái)自相關(guān)話(huà)題

  文章采集調用(1.用python爬取代理批量采集實(shí)現方法:anyproxy+js)
  微信公眾號文章爬取方法整理1.用python爬取
  php
  實(shí)現方法:通過(guò)微信提供的公眾號文章調用接口,實(shí)現抓取公眾號文章html的功能
  步驟:java
  1.需要安裝python selenium模塊包,使用selenium中的webdriver驅動(dòng)瀏覽器獲取cookies,達到登錄的效果;Python
  2.使用webdriver功能需要安裝對應瀏覽器的驅動(dòng)插件。我在這里使用谷歌瀏覽器進(jìn)行測試:
  谷歌瀏覽器版本是 52.0.2743.6 ;
  chromedriver版本為:V2.23
  注意:谷歌瀏覽器版本和chromedriver需要對應,否則啟動(dòng)時(shí)會(huì )報錯?!靖剑簊elenium的chromedriver和chrome版本映射表(更新為v2.30))】web
  3.微信公眾號登錄地址:chrome
  4.微信公眾號文章界面地址可以在微信公眾號后臺創(chuàng )建圖文信息,從超鏈接函數中獲?。簲祿?br />   5.搜索公眾號api
  6.獲取要爬取公眾號的fakeid瀏覽器
  7.選擇要爬取的公眾號,獲取文章接口地址微信
  8.文章列表翻頁(yè)和內容獲取
  2.AnyProxy 代理批量采集
  實(shí)現方式:anyproxy+js
  實(shí)現方式:anyproxy+java+webmagic
  3.FiddlerCore
  實(shí)現方式:抓包工具,Fiddler4
  經(jīng)過(guò)多個(gè)賬號的抓包分析,可以確認:
  _biz:這個(gè)14位的字符串是每一個(gè)公眾號的“id”,搜狗的微信平臺能夠得到
uin:與訪(fǎng)問(wèn)者有關(guān),微信號id
key:和所訪(fǎng)問(wèn)的公眾號有關(guān)
  步:
  1、編寫(xiě)按鈕向導腳本,在手機端自動(dòng)點(diǎn)擊公眾號文章的列表頁(yè)面,即“查看歷史消息”;
  2、使用fiddler代理劫持??手機訪(fǎng)問(wèn),將URL轉發(fā)到php編寫(xiě)的本地網(wǎng)頁(yè);
  3、將接收到的URL備份到php網(wǎng)頁(yè)上的數據庫中;
  4、使用python從數據庫中檢索URL,然后進(jìn)行正常爬取。
  在爬升過(guò)程中發(fā)現了一個(gè)問(wèn)題:
  如果只是想爬文章的內容,貌似沒(méi)有訪(fǎng)問(wèn)頻率限制,但是如果你想爬讀點(diǎn)贊數,達到一定頻率后,返回值會(huì )變成null,我設置的時(shí)間間隔為10秒,可以正常取到。在這個(gè)頻率下,一個(gè)小時(shí)只能取到 360 條,沒(méi)有實(shí)際意義。
  4.青波新榜
  如果你只是想看數據,你可以不花錢(qián)只看每日清單。如果你需要訪(fǎng)問(wèn)自己的系統,他們也提供了一個(gè)api接口 查看全部

  文章采集調用(1.用python爬取代理批量采集實(shí)現方法:anyproxy+js)
  微信公眾號文章爬取方法整理1.用python爬取
  php
  實(shí)現方法:通過(guò)微信提供的公眾號文章調用接口,實(shí)現抓取公眾號文章html的功能
  步驟:java
  1.需要安裝python selenium模塊包,使用selenium中的webdriver驅動(dòng)瀏覽器獲取cookies,達到登錄的效果;Python
  2.使用webdriver功能需要安裝對應瀏覽器的驅動(dòng)插件。我在這里使用谷歌瀏覽器進(jìn)行測試:
  谷歌瀏覽器版本是 52.0.2743.6 ;
  chromedriver版本為:V2.23
  注意:谷歌瀏覽器版本和chromedriver需要對應,否則啟動(dòng)時(shí)會(huì )報錯?!靖剑簊elenium的chromedriver和chrome版本映射表(更新為v2.30))】web
  3.微信公眾號登錄地址:chrome
  4.微信公眾號文章界面地址可以在微信公眾號后臺創(chuàng )建圖文信息,從超鏈接函數中獲?。簲祿?br />   5.搜索公眾號api
  6.獲取要爬取公眾號的fakeid瀏覽器
  7.選擇要爬取的公眾號,獲取文章接口地址微信
  8.文章列表翻頁(yè)和內容獲取
  2.AnyProxy 代理批量采集
  實(shí)現方式:anyproxy+js
  實(shí)現方式:anyproxy+java+webmagic
  3.FiddlerCore
  實(shí)現方式:抓包工具,Fiddler4
  經(jīng)過(guò)多個(gè)賬號的抓包分析,可以確認:
  _biz:這個(gè)14位的字符串是每一個(gè)公眾號的“id”,搜狗的微信平臺能夠得到
uin:與訪(fǎng)問(wèn)者有關(guān),微信號id
key:和所訪(fǎng)問(wèn)的公眾號有關(guān)
  步:
  1、編寫(xiě)按鈕向導腳本,在手機端自動(dòng)點(diǎn)擊公眾號文章的列表頁(yè)面,即“查看歷史消息”;
  2、使用fiddler代理劫持??手機訪(fǎng)問(wèn),將URL轉發(fā)到php編寫(xiě)的本地網(wǎng)頁(yè);
  3、將接收到的URL備份到php網(wǎng)頁(yè)上的數據庫中;
  4、使用python從數據庫中檢索URL,然后進(jìn)行正常爬取。
  在爬升過(guò)程中發(fā)現了一個(gè)問(wèn)題:
  如果只是想爬文章的內容,貌似沒(méi)有訪(fǎng)問(wèn)頻率限制,但是如果你想爬讀點(diǎn)贊數,達到一定頻率后,返回值會(huì )變成null,我設置的時(shí)間間隔為10秒,可以正常取到。在這個(gè)頻率下,一個(gè)小時(shí)只能取到 360 條,沒(méi)有實(shí)際意義。
  4.青波新榜
  如果你只是想看數據,你可以不花錢(qián)只看每日清單。如果你需要訪(fǎng)問(wèn)自己的系統,他們也提供了一個(gè)api接口

文章采集調用(設為“星標”,好文章不錯過(guò)!(組圖))

采集交流 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 170 次瀏覽 ? 2022-04-10 19:27 ? 來(lái)自相關(guān)話(huà)題

  文章采集調用(設為“星標”,好文章不錯過(guò)!(組圖))
  設置為“star”,所以文章不要錯過(guò)!
  
  1 服務(wù)跟蹤系統的意義
  
  1.1 快速定位請求失敗的原因
  
  在微服務(wù)架構下,有很多服務(wù)。如果上游請求失敗,要找出是哪個(gè)應用程序導致它是一場(chǎng)噩夢(mèng)!
  
  如果有系統,它可以跟蹤記錄用戶(hù)請求發(fā)起了哪些調用,處理了哪些服務(wù),并記錄了每次調用所涉及的服務(wù)的詳細信息。如果調用失敗,可以通過(guò)日志快速定位問(wèn)題!
  1.2 優(yōu)化系統瓶頸
  
  通過(guò)記錄調用經(jīng)過(guò)的每個(gè)環(huán)節的耗時(shí),可以快速定位整個(gè)系統的瓶頸點(diǎn)。比如你訪(fǎng)問(wèn)xxx網(wǎng)站的首頁(yè),發(fā)現速度很慢,可能是運營(yíng)商網(wǎng)絡(luò )延遲、網(wǎng)關(guān)系統異常、服務(wù)異常、緩存或者DB異常。通過(guò)服務(wù)跟蹤,可以從上帝視角看到整個(gè)系統的瓶頸點(diǎn),然后針對性的優(yōu)化。
  1.3 優(yōu)化鏈接調用
  
  分析調用經(jīng)過(guò)的路徑,評估是否合理,每個(gè)依賴(lài)是否必要,是否可以通過(guò)業(yè)務(wù)優(yōu)化減少服務(wù)依賴(lài)。
  一般情況下,服務(wù)部署在多個(gè)數據中心,實(shí)現異地容災。此時(shí)服務(wù)A經(jīng)常調用另一個(gè)數據中心的服務(wù)B,而不會(huì )調用同一個(gè)數據中心的服務(wù)B。
  跨數據中心的呼叫會(huì )根據距離有一定的網(wǎng)絡(luò )延遲,這對于某些業(yè)務(wù)來(lái)說(shuō)是無(wú)法接受的。通過(guò)分析調用鏈,可以識別和優(yōu)化跨數據中心的服務(wù)調用。
  1.4 生成網(wǎng)絡(luò )拓撲
  
  通過(guò)記錄的鏈路信息,可以生成系統的網(wǎng)絡(luò )調用拓撲圖,可以反映系統依賴(lài)哪些服務(wù),服務(wù)之間的調用關(guān)系是什么,一目了然。
  服務(wù)調用的詳細信息也可以標注在網(wǎng)絡(luò )拓撲圖上,也可以起到服務(wù)監控的作用。
  1.5 數據透傳
  
  業(yè)務(wù)中經(jīng)常有需求,期望從調用開(kāi)始就可以傳遞一些用戶(hù)數據,讓系統中的每個(gè)服務(wù)都能獲取到這些信息。比如一個(gè)業(yè)務(wù)要做一些A/B測試,想把A/B測試的切換邏輯一路向下通過(guò)服務(wù)跟蹤系統,經(jīng)過(guò)的每一層服務(wù)都可以得到切換值,從而可以統一A/B測試。.
  
  2 服務(wù)跟蹤系統原理
  
  服務(wù)跟蹤系統的鼻祖:Google 的論文 Dapper, a Large-Scale Distributed Systems Tracing Infrastructure 詳細解釋了服務(wù)跟蹤系統的實(shí)現原理。
  2.1 核心概念
  
  
  
  跟蹤標識
  
  全局唯一的 64 位整數,用于標識特定的請求 ID。
  它在 RPC 調用的網(wǎng)絡(luò )鏈路中不斷傳輸,將一個(gè)請求在系統中經(jīng)過(guò)的所有路徑串聯(lián)起來(lái)。
  
  跨度ID
  
  它用于標識一個(gè)RPC調用在分布式請求中的位置,以及區分系統中不同服務(wù)之間的調用順序。
  當用戶(hù)的請求進(jìn)入系統時(shí),在RPC調用網(wǎng)絡(luò )第一層A時(shí)spanId初始值為0,進(jìn)入下一層RPC調用B時(shí)spanId為0.1,并繼續進(jìn)入下一層RPC調用在C中,spanId為0.1.1,與B同層的RPC調用E的spanId為0.2,這樣某個(gè)RPC請求就可以通過(guò)spanId在系統中定位到調用中的位置,以及它的上下游依賴(lài)是誰(shuí)。這類(lèi)似于霍夫曼編碼。
  
  注解
  
  用于自定義業(yè)務(wù)的嵌入點(diǎn)數據??梢允菢I(yè)務(wù)感興趣并想上傳到后端的數據,比如一個(gè)請求的用戶(hù)UID。
  商家自定義一些自己感興趣的數據,除了上傳traceId、spanId等基本信息外,添加一些自己感興趣的信息。
  
  3 服務(wù)跟蹤系統的實(shí)施
  
  服務(wù)跟蹤系統可分為三層:
  3.1 個(gè)數據采集圖層
  
  在系統的不同模塊中嵌入點(diǎn),采集數據并上報給數據處理層進(jìn)行處理。
  那么如何掩埋數據呢?結合下圖來(lái)了解數據嵌入的過(guò)程。
  
  以紅框圈出的A調用B的過(guò)程為例,一個(gè)RPC請求可以分為四個(gè)階段。
  CS(Client Send)階段:客戶(hù)端發(fā)起請求并生成調用的上下文
  SR(Server Recieve)階段:服務(wù)器接收請求并生成上下文
  SS(Server Send)階段:服務(wù)器返回請求。在此階段,將報告服務(wù)器上下文數據。下圖顯示上報數據為:traceId=123456, spanId=0.1, appKey=B, method=B.method, start=103, duration=38
  CR(Client Recieve)階段:客戶(hù)端接收返回的結果。此階段將報告客戶(hù)端上下文數據。上報數據為:traceid=123456,spanId=0.1,appKey=A,method=B.method,start=103,duration=38。
  
  3.2 數據處理層
  
  按需計算data采集層上報的數據,然后存儲在地面上供查詢(xún)使用。
  據我所知,數據處理需求一般分為兩類(lèi),一類(lèi)是實(shí)時(shí)計算需求,一類(lèi)是離線(xiàn)計算需求。
  實(shí)時(shí)計算要求需要較高的計算效率。一般要求采集到的鏈路數據可以秒級聚合,實(shí)時(shí)查詢(xún)。但是,離線(xiàn)計算的需求并不需要那么高的計算效率。一般可以在小時(shí)級別完成鏈路數據的聚合計算,一般用于數據匯總統計。對于這兩類(lèi)不同的數據處理需求,所使用的計算方式和存儲也是不同的。
  3.3 數據表示層
  
  數據展示層的作用是將處理后的鏈接信息以圖形方式展示給用戶(hù)。
  主要使用以下兩個(gè)圖形:
  
  調用鏈接圖
  
  從這張圖中可以看出:
  在實(shí)際項目中,調用鏈路圖主要用于故障定位。例如,如果用戶(hù)調用失敗,可以通過(guò)調用鏈路圖查詢(xún)用戶(hù)調用經(jīng)過(guò)了哪些鏈路,以及調用失敗的層級。造成的。
  
  呼叫拓撲
  
  呼叫拓撲圖是全局視圖圖。在實(shí)際項目中,主要用于全局監控,以發(fā)現系統中的異常點(diǎn)并快速做出決策。比如某個(gè)服務(wù)突然出現異常,在調用鏈路拓撲圖中可以看出該服務(wù)的調用時(shí)間增加了,可以用紅色圖案標注,用于監控和告警。
  參考
  過(guò)去推薦
  廠(chǎng)家如何解決數值精度/舍入/溢出問(wèn)題
  大廠(chǎng)數據庫事務(wù)實(shí)踐——事務(wù)生效后能否正確回滾?
  在線(xiàn)問(wèn)題事跡(一)數據庫事務(wù)沒(méi)有生效? 查看全部

  文章采集調用(設為“星標”,好文章不錯過(guò)!(組圖))
  設置為“star”,所以文章不要錯過(guò)!
  
  1 服務(wù)跟蹤系統的意義
  
  1.1 快速定位請求失敗的原因
  
  在微服務(wù)架構下,有很多服務(wù)。如果上游請求失敗,要找出是哪個(gè)應用程序導致它是一場(chǎng)噩夢(mèng)!
  
  如果有系統,它可以跟蹤記錄用戶(hù)請求發(fā)起了哪些調用,處理了哪些服務(wù),并記錄了每次調用所涉及的服務(wù)的詳細信息。如果調用失敗,可以通過(guò)日志快速定位問(wèn)題!
  1.2 優(yōu)化系統瓶頸
  
  通過(guò)記錄調用經(jīng)過(guò)的每個(gè)環(huán)節的耗時(shí),可以快速定位整個(gè)系統的瓶頸點(diǎn)。比如你訪(fǎng)問(wèn)xxx網(wǎng)站的首頁(yè),發(fā)現速度很慢,可能是運營(yíng)商網(wǎng)絡(luò )延遲、網(wǎng)關(guān)系統異常、服務(wù)異常、緩存或者DB異常。通過(guò)服務(wù)跟蹤,可以從上帝視角看到整個(gè)系統的瓶頸點(diǎn),然后針對性的優(yōu)化。
  1.3 優(yōu)化鏈接調用
  
  分析調用經(jīng)過(guò)的路徑,評估是否合理,每個(gè)依賴(lài)是否必要,是否可以通過(guò)業(yè)務(wù)優(yōu)化減少服務(wù)依賴(lài)。
  一般情況下,服務(wù)部署在多個(gè)數據中心,實(shí)現異地容災。此時(shí)服務(wù)A經(jīng)常調用另一個(gè)數據中心的服務(wù)B,而不會(huì )調用同一個(gè)數據中心的服務(wù)B。
  跨數據中心的呼叫會(huì )根據距離有一定的網(wǎng)絡(luò )延遲,這對于某些業(yè)務(wù)來(lái)說(shuō)是無(wú)法接受的。通過(guò)分析調用鏈,可以識別和優(yōu)化跨數據中心的服務(wù)調用。
  1.4 生成網(wǎng)絡(luò )拓撲
  
  通過(guò)記錄的鏈路信息,可以生成系統的網(wǎng)絡(luò )調用拓撲圖,可以反映系統依賴(lài)哪些服務(wù),服務(wù)之間的調用關(guān)系是什么,一目了然。
  服務(wù)調用的詳細信息也可以標注在網(wǎng)絡(luò )拓撲圖上,也可以起到服務(wù)監控的作用。
  1.5 數據透傳
  
  業(yè)務(wù)中經(jīng)常有需求,期望從調用開(kāi)始就可以傳遞一些用戶(hù)數據,讓系統中的每個(gè)服務(wù)都能獲取到這些信息。比如一個(gè)業(yè)務(wù)要做一些A/B測試,想把A/B測試的切換邏輯一路向下通過(guò)服務(wù)跟蹤系統,經(jīng)過(guò)的每一層服務(wù)都可以得到切換值,從而可以統一A/B測試。.
  
  2 服務(wù)跟蹤系統原理
  
  服務(wù)跟蹤系統的鼻祖:Google 的論文 Dapper, a Large-Scale Distributed Systems Tracing Infrastructure 詳細解釋了服務(wù)跟蹤系統的實(shí)現原理。
  2.1 核心概念
  
  
  
  跟蹤標識
  
  全局唯一的 64 位整數,用于標識特定的請求 ID。
  它在 RPC 調用的網(wǎng)絡(luò )鏈路中不斷傳輸,將一個(gè)請求在系統中經(jīng)過(guò)的所有路徑串聯(lián)起來(lái)。
  
  跨度ID
  
  它用于標識一個(gè)RPC調用在分布式請求中的位置,以及區分系統中不同服務(wù)之間的調用順序。
  當用戶(hù)的請求進(jìn)入系統時(shí),在RPC調用網(wǎng)絡(luò )第一層A時(shí)spanId初始值為0,進(jìn)入下一層RPC調用B時(shí)spanId為0.1,并繼續進(jìn)入下一層RPC調用在C中,spanId為0.1.1,與B同層的RPC調用E的spanId為0.2,這樣某個(gè)RPC請求就可以通過(guò)spanId在系統中定位到調用中的位置,以及它的上下游依賴(lài)是誰(shuí)。這類(lèi)似于霍夫曼編碼。
  
  注解
  
  用于自定義業(yè)務(wù)的嵌入點(diǎn)數據??梢允菢I(yè)務(wù)感興趣并想上傳到后端的數據,比如一個(gè)請求的用戶(hù)UID。
  商家自定義一些自己感興趣的數據,除了上傳traceId、spanId等基本信息外,添加一些自己感興趣的信息。
  
  3 服務(wù)跟蹤系統的實(shí)施
  
  服務(wù)跟蹤系統可分為三層:
  3.1 個(gè)數據采集圖層
  
  在系統的不同模塊中嵌入點(diǎn),采集數據并上報給數據處理層進(jìn)行處理。
  那么如何掩埋數據呢?結合下圖來(lái)了解數據嵌入的過(guò)程。
  
  以紅框圈出的A調用B的過(guò)程為例,一個(gè)RPC請求可以分為四個(gè)階段。
  CS(Client Send)階段:客戶(hù)端發(fā)起請求并生成調用的上下文
  SR(Server Recieve)階段:服務(wù)器接收請求并生成上下文
  SS(Server Send)階段:服務(wù)器返回請求。在此階段,將報告服務(wù)器上下文數據。下圖顯示上報數據為:traceId=123456, spanId=0.1, appKey=B, method=B.method, start=103, duration=38
  CR(Client Recieve)階段:客戶(hù)端接收返回的結果。此階段將報告客戶(hù)端上下文數據。上報數據為:traceid=123456,spanId=0.1,appKey=A,method=B.method,start=103,duration=38。
  
  3.2 數據處理層
  
  按需計算data采集層上報的數據,然后存儲在地面上供查詢(xún)使用。
  據我所知,數據處理需求一般分為兩類(lèi),一類(lèi)是實(shí)時(shí)計算需求,一類(lèi)是離線(xiàn)計算需求。
  實(shí)時(shí)計算要求需要較高的計算效率。一般要求采集到的鏈路數據可以秒級聚合,實(shí)時(shí)查詢(xún)。但是,離線(xiàn)計算的需求并不需要那么高的計算效率。一般可以在小時(shí)級別完成鏈路數據的聚合計算,一般用于數據匯總統計。對于這兩類(lèi)不同的數據處理需求,所使用的計算方式和存儲也是不同的。
  3.3 數據表示層
  
  數據展示層的作用是將處理后的鏈接信息以圖形方式展示給用戶(hù)。
  主要使用以下兩個(gè)圖形:
  
  調用鏈接圖
  
  從這張圖中可以看出:
  在實(shí)際項目中,調用鏈路圖主要用于故障定位。例如,如果用戶(hù)調用失敗,可以通過(guò)調用鏈路圖查詢(xún)用戶(hù)調用經(jīng)過(guò)了哪些鏈路,以及調用失敗的層級。造成的。
  
  呼叫拓撲
  
  呼叫拓撲圖是全局視圖圖。在實(shí)際項目中,主要用于全局監控,以發(fā)現系統中的異常點(diǎn)并快速做出決策。比如某個(gè)服務(wù)突然出現異常,在調用鏈路拓撲圖中可以看出該服務(wù)的調用時(shí)間增加了,可以用紅色圖案標注,用于監控和告警。
  參考
  過(guò)去推薦
  廠(chǎng)家如何解決數值精度/舍入/溢出問(wèn)題
  大廠(chǎng)數據庫事務(wù)實(shí)踐——事務(wù)生效后能否正確回滾?
  在線(xiàn)問(wèn)題事跡(一)數據庫事務(wù)沒(méi)有生效?

文章采集調用(這部分資料大部分都是都是:如何編程經(jīng)驗總結了一下,效果并不好)

采集交流 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 124 次瀏覽 ? 2022-04-10 19:23 ? 來(lái)自相關(guān)話(huà)題

  文章采集調用(這部分資料大部分都是都是:如何編程經(jīng)驗總結了一下,效果并不好)
  主機:ubuntu 10.10 開(kāi)發(fā)板:Tiny6410 交叉編譯工具鏈:atm-linux-gcc 4.3.2qt 版本:QtEmbedded-4.5.2 - arm 最近在Tiny6410上編程攝像頭的時(shí)候,從網(wǎng)上找了很多資料學(xué)習,但是效果不好,因為網(wǎng)上大部分資料都不是很詳細,如果有V4L2編程經(jīng)驗的話(huà). 都差不多,不過(guò)對于我這種剛入門(mén)的人來(lái)說(shuō)太麻煩了。這部分信息大部分是:1、詳細介紹如何編程V4L2,但沒(méi)有提供源代碼示例。2、提供了源代碼,但注釋很少。難以閱讀。于是總結了一篇文章文章,總結了編程心得,這些例子可以在Tiny6410開(kāi)發(fā)板上運行,也可以直接在ubuntu 10.10上運行,可以使用的攝像頭有OV9650、USB接口OV301等,只需對源碼稍作改動(dòng)即可。關(guān)于 videodevice 是我在網(wǎng)上找到的一條資料。我覺(jué)得他寫(xiě)的很好,所以也收錄在里面供大家參考。如果您有任何問(wèn)題,請與我聯(lián)系。我的郵箱是:我要注意:我上次上傳的代碼不是我上次修改的代碼,雖然沒(méi)有問(wèn)題,但是我還是覺(jué)得再上傳一次就好了,就是不知道怎么改刪除之前上傳的代碼,只能重新發(fā)送。關(guān)于 videodevice 是我在網(wǎng)上找到的一條資料。我覺(jué)得他寫(xiě)的很好,所以也收錄在里面供大家參考。如果您有任何問(wèn)題,請與我聯(lián)系。我的郵箱是:我要注意:我上次上傳的代碼不是我上次修改的代碼,雖然沒(méi)有問(wèn)題,但是我還是覺(jué)得再上傳一次就好了,就是不知道怎么改刪除之前上傳的代碼,只能重新發(fā)送。關(guān)于 videodevice 是我在網(wǎng)上找到的一條資料。我覺(jué)得他寫(xiě)的很好,所以也收錄在里面供大家參考。如果您有任何問(wèn)題,請與我聯(lián)系。我的郵箱是:我要注意:我上次上傳的代碼不是我上次修改的代碼,雖然沒(méi)有問(wèn)題,但是我還是覺(jué)得再上傳一次就好了,就是不知道怎么改刪除之前上傳的代碼,只能重新發(fā)送。 查看全部

  文章采集調用(這部分資料大部分都是都是:如何編程經(jīng)驗總結了一下,效果并不好)
  主機:ubuntu 10.10 開(kāi)發(fā)板:Tiny6410 交叉編譯工具鏈:atm-linux-gcc 4.3.2qt 版本:QtEmbedded-4.5.2 - arm 最近在Tiny6410上編程攝像頭的時(shí)候,從網(wǎng)上找了很多資料學(xué)習,但是效果不好,因為網(wǎng)上大部分資料都不是很詳細,如果有V4L2編程經(jīng)驗的話(huà). 都差不多,不過(guò)對于我這種剛入門(mén)的人來(lái)說(shuō)太麻煩了。這部分信息大部分是:1、詳細介紹如何編程V4L2,但沒(méi)有提供源代碼示例。2、提供了源代碼,但注釋很少。難以閱讀。于是總結了一篇文章文章,總結了編程心得,這些例子可以在Tiny6410開(kāi)發(fā)板上運行,也可以直接在ubuntu 10.10上運行,可以使用的攝像頭有OV9650、USB接口OV301等,只需對源碼稍作改動(dòng)即可。關(guān)于 videodevice 是我在網(wǎng)上找到的一條資料。我覺(jué)得他寫(xiě)的很好,所以也收錄在里面供大家參考。如果您有任何問(wèn)題,請與我聯(lián)系。我的郵箱是:我要注意:我上次上傳的代碼不是我上次修改的代碼,雖然沒(méi)有問(wèn)題,但是我還是覺(jué)得再上傳一次就好了,就是不知道怎么改刪除之前上傳的代碼,只能重新發(fā)送。關(guān)于 videodevice 是我在網(wǎng)上找到的一條資料。我覺(jué)得他寫(xiě)的很好,所以也收錄在里面供大家參考。如果您有任何問(wèn)題,請與我聯(lián)系。我的郵箱是:我要注意:我上次上傳的代碼不是我上次修改的代碼,雖然沒(méi)有問(wèn)題,但是我還是覺(jué)得再上傳一次就好了,就是不知道怎么改刪除之前上傳的代碼,只能重新發(fā)送。關(guān)于 videodevice 是我在網(wǎng)上找到的一條資料。我覺(jué)得他寫(xiě)的很好,所以也收錄在里面供大家參考。如果您有任何問(wèn)題,請與我聯(lián)系。我的郵箱是:我要注意:我上次上傳的代碼不是我上次修改的代碼,雖然沒(méi)有問(wèn)題,但是我還是覺(jué)得再上傳一次就好了,就是不知道怎么改刪除之前上傳的代碼,只能重新發(fā)送。

文章采集調用(文章采集調用服務(wù)的xml格式的接口,無(wú)需restfulapi)

采集交流 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 140 次瀏覽 ? 2022-04-09 23:03 ? 來(lái)自相關(guān)話(huà)題

  文章采集調用(文章采集調用服務(wù)的xml格式的接口,無(wú)需restfulapi)
  文章采集調用服務(wù)的xml格式的接口,無(wú)需restfulapi,一切交給c++,或者用epoll、select等異步網(wǎng)絡(luò )調用即可.現有文章內容抓取及商品xml接口通過(guò)開(kāi)發(fā)一個(gè)簡(jiǎn)單的爬蟲(chóng),能夠最大限度的節省url請求和返回的訪(fǎng)問(wèn)成本。本小節以杭州某地的某線(xiàn)索網(wǎng)站為例講解如何開(kāi)發(fā)一個(gè)簡(jiǎn)單的爬蟲(chóng)。由于杭州市的所有信息全部都在這一小塊地圖上,爬蟲(chóng)必須讀取這些數據,可以很快速的進(jìn)行數據采集。
  爬蟲(chóng)的實(shí)現要先針對這個(gè)網(wǎng)站的數據進(jìn)行分析,得到每個(gè)url對應的vi信息即當前頁(yè)內容,以及當前頁(yè)內容對應的url之前的所有歷史價(jià)格數據。得到每個(gè)url對應的vi信息即當前頁(yè)內容對應的url之前的所有歷史價(jià)格數據爬蟲(chóng)的代碼是通過(guò)兩個(gè)c++的源文件完成。以杭州市某的某線(xiàn)索網(wǎng)站為例(杭州市的網(wǎng)址則在此網(wǎng)址后面存放),可以理解爬蟲(chóng)只需要通過(guò)url完成第一步所有的任務(wù),然后解析所有url的內容返回給服務(wù)端即可。
<p>有了數據,接下來(lái)就是網(wǎng)站的代碼實(shí)現,以及如何抓取數據了。爬蟲(chóng)的代碼:#include#include#includeusingnamespacestd;constintmaxpage=10;//一頁(yè)的長(cháng)度#includeintmain(){void*path;stringfilename;charcontent[]="/";charcontent[]="\n";string[]arrays;present_content(path);filename=0;file_tindex;charlines[]=path.size();char[]next;for(index=0;index 查看全部

  文章采集調用(文章采集調用服務(wù)的xml格式的接口,無(wú)需restfulapi)
  文章采集調用服務(wù)的xml格式的接口,無(wú)需restfulapi,一切交給c++,或者用epoll、select等異步網(wǎng)絡(luò )調用即可.現有文章內容抓取及商品xml接口通過(guò)開(kāi)發(fā)一個(gè)簡(jiǎn)單的爬蟲(chóng),能夠最大限度的節省url請求和返回的訪(fǎng)問(wèn)成本。本小節以杭州某地的某線(xiàn)索網(wǎng)站為例講解如何開(kāi)發(fā)一個(gè)簡(jiǎn)單的爬蟲(chóng)。由于杭州市的所有信息全部都在這一小塊地圖上,爬蟲(chóng)必須讀取這些數據,可以很快速的進(jìn)行數據采集。
  爬蟲(chóng)的實(shí)現要先針對這個(gè)網(wǎng)站的數據進(jìn)行分析,得到每個(gè)url對應的vi信息即當前頁(yè)內容,以及當前頁(yè)內容對應的url之前的所有歷史價(jià)格數據。得到每個(gè)url對應的vi信息即當前頁(yè)內容對應的url之前的所有歷史價(jià)格數據爬蟲(chóng)的代碼是通過(guò)兩個(gè)c++的源文件完成。以杭州市某的某線(xiàn)索網(wǎng)站為例(杭州市的網(wǎng)址則在此網(wǎng)址后面存放),可以理解爬蟲(chóng)只需要通過(guò)url完成第一步所有的任務(wù),然后解析所有url的內容返回給服務(wù)端即可。
<p>有了數據,接下來(lái)就是網(wǎng)站的代碼實(shí)現,以及如何抓取數據了。爬蟲(chóng)的代碼:#include#include#includeusingnamespacestd;constintmaxpage=10;//一頁(yè)的長(cháng)度#includeintmain(){void*path;stringfilename;charcontent[]="/";charcontent[]="\n";string[]arrays;present_content(path);filename=0;file_tindex;charlines[]=path.size();char[]next;for(index=0;index

文章采集調用(通過(guò)SpringBootActuatorWebAPI監控應用狀態(tài)actuatorWeb)

采集交流 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 140 次瀏覽 ? 2022-04-09 18:42 ? 來(lái)自相關(guān)話(huà)題

  文章采集調用(通過(guò)SpringBootActuatorWebAPI監控應用狀態(tài)actuatorWeb)
  環(huán)境需求案例:通過(guò) Spring Boot Actuator Web API 監控應用狀態(tài)
  執行器提供了一個(gè)健康端點(diǎn),用于獲取有關(guān)應用程序健康的詳細信息。
  官方文檔地址:#health
  URL地址是:
  /執行器/健康
  返回結果(JSON數據格式):
  {
"status": "UP",
"components": {
"custom": {
"status": "UP",
"details": {
"app": "Alive and Kicking",
"error": "Nothing! I&#39;m good."
}
},
"diskSpace": {
"status": "UP",
"details": {
"total": 52776349696,
"free": 43368595456,
"threshold": 10485760
}
},
"ping": {
"status": "UP"
}
}
}
  配置監控項
  建議使用Zabbix的主監控項+從屬監控項(相關(guān)項)實(shí)現采集一次多個(gè)數據調用,減少API調用次數。
  第一步:創(chuàng )建主監控項
  創(chuàng )建監控項,修改如下配置:
  如果API接口需要認證,可以設置HTTP認證。使用宏變量支持用戶(hù)名和密碼。
  
  
  配置完成后,點(diǎn)擊下方測試,點(diǎn)擊獲取值并測試,查看是否可以正確獲取數據。
  
  第二步:創(chuàng )建依賴(lài)監控項(相關(guān)項)
  假設您需要監控應用程序的狀態(tài)和磁盤(pán)的剩余空間。
  指標 1:監控應用程序狀態(tài)
  JSONPath語(yǔ)法說(shuō)明參考官方文檔:
  創(chuàng )建監控項,修改如下配置:
  
  將步驟添加到“進(jìn)程”選項卡:
  
  點(diǎn)擊下面的Test all steps來(lái)驗證配置,在value中填入主監控項test獲取的數據,點(diǎn)擊Test查看是否可以正確獲取數據。
  
  指標 2:監控磁盤(pán)剩余空間
  創(chuàng )建監控項,修改如下配置:
  
  將步驟添加到“進(jìn)程”選項卡:
  
  點(diǎn)擊下面的Test all steps來(lái)驗證配置,在value中填入主監控項test獲取的數據,點(diǎn)擊Test查看是否可以正確獲取數據。
  
  檢查最新數據是否正常采集
  注:依賴(lài)監控項(相關(guān)項)的數據更新周期由主監控項設置的更新周期決定
  
  至此,監控項的配置已經(jīng)完成,接下來(lái)就可以根據實(shí)際情況配置相應的觸發(fā)器了。
  配置模板時(shí),可以將主監控項中的URL配置為宏宏變量,例如:{$HOST}:{$PORT}/actuator/health,這樣可以在鏈接時(shí)為不同的主機設置宏變量模板(用戶(hù)名和密碼也可以這樣配置)。 查看全部

  文章采集調用(通過(guò)SpringBootActuatorWebAPI監控應用狀態(tài)actuatorWeb)
  環(huán)境需求案例:通過(guò) Spring Boot Actuator Web API 監控應用狀態(tài)
  執行器提供了一個(gè)健康端點(diǎn),用于獲取有關(guān)應用程序健康的詳細信息。
  官方文檔地址:#health
  URL地址是:
  /執行器/健康
  返回結果(JSON數據格式):
  {
"status": "UP",
"components": {
"custom": {
"status": "UP",
"details": {
"app": "Alive and Kicking",
"error": "Nothing! I&#39;m good."
}
},
"diskSpace": {
"status": "UP",
"details": {
"total": 52776349696,
"free": 43368595456,
"threshold": 10485760
}
},
"ping": {
"status": "UP"
}
}
}
  配置監控項
  建議使用Zabbix的主監控項+從屬監控項(相關(guān)項)實(shí)現采集一次多個(gè)數據調用,減少API調用次數。
  第一步:創(chuàng )建主監控項
  創(chuàng )建監控項,修改如下配置:
  如果API接口需要認證,可以設置HTTP認證。使用宏變量支持用戶(hù)名和密碼。
  
  
  配置完成后,點(diǎn)擊下方測試,點(diǎn)擊獲取值并測試,查看是否可以正確獲取數據。
  
  第二步:創(chuàng )建依賴(lài)監控項(相關(guān)項)
  假設您需要監控應用程序的狀態(tài)和磁盤(pán)的剩余空間。
  指標 1:監控應用程序狀態(tài)
  JSONPath語(yǔ)法說(shuō)明參考官方文檔:
  創(chuàng )建監控項,修改如下配置:
  
  將步驟添加到“進(jìn)程”選項卡:
  
  點(diǎn)擊下面的Test all steps來(lái)驗證配置,在value中填入主監控項test獲取的數據,點(diǎn)擊Test查看是否可以正確獲取數據。
  
  指標 2:監控磁盤(pán)剩余空間
  創(chuàng )建監控項,修改如下配置:
  
  將步驟添加到“進(jìn)程”選項卡:
  
  點(diǎn)擊下面的Test all steps來(lái)驗證配置,在value中填入主監控項test獲取的數據,點(diǎn)擊Test查看是否可以正確獲取數據。
  
  檢查最新數據是否正常采集
  注:依賴(lài)監控項(相關(guān)項)的數據更新周期由主監控項設置的更新周期決定
  
  至此,監控項的配置已經(jīng)完成,接下來(lái)就可以根據實(shí)際情況配置相應的觸發(fā)器了。
  配置模板時(shí),可以將主監控項中的URL配置為宏宏變量,例如:{$HOST}:{$PORT}/actuator/health,這樣可以在鏈接時(shí)為不同的主機設置宏變量模板(用戶(hù)名和密碼也可以這樣配置)。

文章采集調用 Java 中拼接 String 的 N 種方式

采集交流 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 168 次瀏覽 ? 2022-05-01 09:32 ? 來(lái)自相關(guān)話(huà)題

  文章采集調用 Java 中拼接 String 的 N 種方式
  
  1. 前言
  Java 提供了拼接 String 字符串的多種方式,不過(guò)有時(shí)候如果我們不注意 null 字符串的話(huà),可能會(huì )把 null 拼接到結果當中,很明顯這不是我們想要的。
  在這篇文章中,將介紹一些在拼接 String 時(shí)避免 null 值的幾種方式。
  2. 問(wèn)題復現
  如果我們想要拼接 String 數組,可以簡(jiǎn)單的使用 + 運算符進(jìn)行拼接,但是可能會(huì )遇到 null 值。
  String[]?values?=?{"https",?"://",?"www.",?"wdbyte",?".com",?null};<br />String?result?=?"";<br /><br />for?(String?value?:?values)?{<br />????result?=?result?+?value;<br />}<br />
  這會(huì )將所有元素拼接到結果字符串中,如下所示:
  https://www.wdbyte.comnull<br />
  但是,我們已經(jīng)發(fā)現問(wèn)題了,最后的 null 值作為字符串也拼接了下來(lái),這顯然不是我們想要的。
  同樣,即使我們在 Java 8 或更高版本上運行,然后使用String.join() 靜態(tài)方法拼接字符串,一樣會(huì )得到帶有 null 值的輸出。
  String[]?values?=?{"https",?"://",?"www.",?"wdbyte",?".com",?null};<br />String?result?=?String.join("",?values);<br />//?output:?https://www.wdbyte.comnull<br />
  下面看看一些可以避免 null 值被拼接下來(lái)的方法,我的期待的輸出結果應該是:
  https://www.wdbyte.com<br />
  3. 使用 + 運算符
  加法符號 + 可以拼接 String 字符串,那么我們只需要在拼接時(shí)進(jìn)行 null 判斷就可以把 null 值替換為空字符串了。
  for?(String?value?:?values)?{<br />??result?=?result?+?(value?==?null???""?:?value);<br />}<br />
  然而,我們知道 String 是一個(gè)不可變對象,使用 + 號會(huì )頻繁的創(chuàng )建字符串對象,每次都會(huì )在內存中創(chuàng )建一個(gè)新的字符串,所以使用 + 符號來(lái)拼接字符串的性能消耗是很高的。
  為了方便后續的代碼演示,我們抽取一個(gè)可以傳入字符串,返回一個(gè)非 null 字符串的方法。
  public?String?nullToString(String?value)?{<br />????return?value?==?null???""?:?value;<br />}<br />
  因此上面的代碼可以改為調用這個(gè)方法:
  for?(String?value?:?values)?{<br />????result?=?result?+?nullToString(value);<br />}<br />
  4. 使用 String.concat()
  String.concat() 是 String 類(lèi)自帶的一個(gè)方法,使用這種方式拼接字符串十分方便。
  for?(String?value?:?values)?{<br />????result?=?result.concat(getNonNullString(value));<br />}<br />
  因為調用了 nullToString() 方法,因此得到的結果中沒(méi)有 null 值。
  5. 使用 StringBuilder
  StringBuilder 類(lèi)提供了很多有用且方便的 String 構建方法。其中比較常用的是 append() 方法,使用 append() 來(lái)拼接字符串,同時(shí)結合 nullToString() 方法來(lái)避免 null 值。
  String[]?values?=?{"https",?"://",?"www.",?"wdbyte",?".com",?null};<br />StringBuilder?result?=?new?StringBuilder();<br />for?(String?value?:?values)?{<br />????result?=?result.append(nullToString(value));<br />}<br />
  可以得到如下結果:
  https://www.wdbyte.com<br />
  6. 使用 StringJoiner 類(lèi) (Java 8+)
  StringJoiner 類(lèi)提供了更強大的字符串拼接功能,不僅可以指定拼接時(shí)的分隔符,還可以指定拼接時(shí)的前綴和后綴,這里我們可以使用它的 add()方法來(lái)拼接字符串。
  同樣的會(huì )用 nullToString() 方法來(lái)避免 null 值。
  String[]?values?=?{"https",?"://",?"www.",?"wdbyte",?".com",?null};<br />StringJoiner?result?=?new?StringJoiner("");<br />for?(String?value?:?values)?{<br />????result?=?result.add(nullToString(value));<br />}<br />
  7. 使用 Streams.filter (Java 8+)
  Stream API 是 Java 8 引入的功能強大的流式操作類(lèi),可以進(jìn)行常見(jiàn)的過(guò)濾、映射、遍歷、分組、統計等操作。其中的過(guò)濾操作 filter 可以接收一個(gè) Predicate 函數,Predicate 函數接口同之前介紹的 Function (opens new window)接口一樣,是一個(gè)函數式接口,它可以接受一個(gè)泛型 參數,返回值為布爾類(lèi)型,Predicate 常用于數據過(guò)濾。
  因此,我們可以定義一個(gè)Predicate 來(lái)檢查為 null 的字符串,然后傳遞給 Stream API 的 filter() 方法。
  最后再使用 Collectors.joining() 方法拼接剩余的非 null 字符串。
  String[]?values?=?{"https",?"://",?"www.",?"wdbyte",?".com",?null};<br />String?result?=?Arrays.stream(values)<br />????.filter(Objects::nonNull)<br />????.collect(Collectors.joining());<br />
  8. 總結
  這篇文章介紹了拼接非 null 字符串的幾種方式,不同的方式可能適合不同的場(chǎng)景,不過(guò)要注意拼接String 字符串是一項昂貴的操作,下面是使用 JMH 對幾種拼接方式進(jìn)行基準測試的結果。
  Benchmark???????????????????Mode???Cnt???????Score????????Error??Units<br />StringConcat.operateAdd?????thrpt???25??13635005.992?±?549759.774??ops/s<br />StringConcat.String.concat??thrpt???25???7465193.417?±?667928.552??ops/s<br />StringConcat.StringBuilder??thrpt???25??13949781.608?±?142001.421??ops/s<br />StringConcat.StringJoiner???thrpt???25???9502405.473?±?211977.433??ops/s<br />StringConcat.StreamFilter???thrpt???25???8998396.107?±?649033.722??ops/s<br />
  可以看到 StringBuilder 的性能是最好的,實(shí)際使用時(shí)要結合具體場(chǎng)景,然后選擇最低的性能開(kāi)銷(xiāo)方式。
  <p data-darkmode-bgcolor="rgb(36, 36, 36)" data-darkmode-original-bgcolor="rgb(255, 255, 255)" data-darkmode-color="rgb(106, 104, 111)" data-darkmode-original-color="rgb(106, 104, 111)" data-darkmode-bgcolor-15923650965579="rgb(36, 36, 36)" data-darkmode-original-bgcolor-15923650965579="rgb(255, 255, 255)" data-darkmode-color-15923650965579="rgb(106, 104, 111)" data-darkmode-original-color-15923650965579="rgb(106, 104, 111)" style="margin-right: 0em;margin-left: 0em;outline: 0px;color: rgb(106, 104, 111);">1.?SQL優(yōu)化萬(wàn)能公式:5 大步驟 + 10 個(gè)案例
  2.?大型 SaaS 平臺產(chǎn)品架構設計
  3.?Spring Cloud 分布式日志采集方案,建議收藏!
  4.?POI 導出 Excel:字體顏色、行列自適應、鎖住、合并單元格、一文搞定……
  
  最近面試BAT,整理一份面試資料《Java面試BATJ通關(guān)手冊》,覆蓋了Java核心技術(shù)、JVM、Java并發(fā)、SSM、微服務(wù)、數據庫、數據結構等等。
  獲取方式:點(diǎn)“在看”,關(guān)注公眾號并回復?Java?領(lǐng)取,更多內容陸續奉上。</p>
  <p data-tool="mdnice編輯器" style="margin-top: 10px;margin-bottom: 10px;padding-top: 8px;padding-bottom: 8px;outline: 0px;white-space: normal;font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-align: right;line-height: 1.6;color: rgb(63, 63, 63);">PS:因公眾號平臺更改了推送規則,如果不想錯過(guò)內容,記得讀完點(diǎn)一下“在看”,加個(gè)“星標”,這樣每次新文章推送才會(huì )第一時(shí)間出現在你的訂閱列表里。
  點(diǎn)“在看”支持小哈呀,謝謝啦<strong style="outline: 0px;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;color: rgb(0, 128, 255);font-size: 15px;"></strong></p> 查看全部

  文章采集調用 Java 中拼接 String 的 N 種方式
  
  1. 前言
  Java 提供了拼接 String 字符串的多種方式,不過(guò)有時(shí)候如果我們不注意 null 字符串的話(huà),可能會(huì )把 null 拼接到結果當中,很明顯這不是我們想要的。
  在這篇文章中,將介紹一些在拼接 String 時(shí)避免 null 值的幾種方式。
  2. 問(wèn)題復現
  如果我們想要拼接 String 數組,可以簡(jiǎn)單的使用 + 運算符進(jìn)行拼接,但是可能會(huì )遇到 null 值。
  String[]?values?=?{"https",?"://",?"www.",?"wdbyte",?".com",?null};<br />String?result?=?"";<br /><br />for?(String?value?:?values)?{<br />????result?=?result?+?value;<br />}<br />
  這會(huì )將所有元素拼接到結果字符串中,如下所示:
  https://www.wdbyte.comnull<br />
  但是,我們已經(jīng)發(fā)現問(wèn)題了,最后的 null 值作為字符串也拼接了下來(lái),這顯然不是我們想要的。
  同樣,即使我們在 Java 8 或更高版本上運行,然后使用String.join() 靜態(tài)方法拼接字符串,一樣會(huì )得到帶有 null 值的輸出。
  String[]?values?=?{"https",?"://",?"www.",?"wdbyte",?".com",?null};<br />String?result?=?String.join("",?values);<br />//?output:?https://www.wdbyte.comnull<br />
  下面看看一些可以避免 null 值被拼接下來(lái)的方法,我的期待的輸出結果應該是:
  https://www.wdbyte.com<br />
  3. 使用 + 運算符
  加法符號 + 可以拼接 String 字符串,那么我們只需要在拼接時(shí)進(jìn)行 null 判斷就可以把 null 值替換為空字符串了。
  for?(String?value?:?values)?{<br />??result?=?result?+?(value?==?null???""?:?value);<br />}<br />
  然而,我們知道 String 是一個(gè)不可變對象,使用 + 號會(huì )頻繁的創(chuàng )建字符串對象,每次都會(huì )在內存中創(chuàng )建一個(gè)新的字符串,所以使用 + 符號來(lái)拼接字符串的性能消耗是很高的。
  為了方便后續的代碼演示,我們抽取一個(gè)可以傳入字符串,返回一個(gè)非 null 字符串的方法。
  public?String?nullToString(String?value)?{<br />????return?value?==?null???""?:?value;<br />}<br />
  因此上面的代碼可以改為調用這個(gè)方法:
  for?(String?value?:?values)?{<br />????result?=?result?+?nullToString(value);<br />}<br />
  4. 使用 String.concat()
  String.concat() 是 String 類(lèi)自帶的一個(gè)方法,使用這種方式拼接字符串十分方便。
  for?(String?value?:?values)?{<br />????result?=?result.concat(getNonNullString(value));<br />}<br />
  因為調用了 nullToString() 方法,因此得到的結果中沒(méi)有 null 值。
  5. 使用 StringBuilder
  StringBuilder 類(lèi)提供了很多有用且方便的 String 構建方法。其中比較常用的是 append() 方法,使用 append() 來(lái)拼接字符串,同時(shí)結合 nullToString() 方法來(lái)避免 null 值。
  String[]?values?=?{"https",?"://",?"www.",?"wdbyte",?".com",?null};<br />StringBuilder?result?=?new?StringBuilder();<br />for?(String?value?:?values)?{<br />????result?=?result.append(nullToString(value));<br />}<br />
  可以得到如下結果:
  https://www.wdbyte.com<br />
  6. 使用 StringJoiner 類(lèi) (Java 8+)
  StringJoiner 類(lèi)提供了更強大的字符串拼接功能,不僅可以指定拼接時(shí)的分隔符,還可以指定拼接時(shí)的前綴和后綴,這里我們可以使用它的 add()方法來(lái)拼接字符串。
  同樣的會(huì )用 nullToString() 方法來(lái)避免 null 值。
  String[]?values?=?{"https",?"://",?"www.",?"wdbyte",?".com",?null};<br />StringJoiner?result?=?new?StringJoiner("");<br />for?(String?value?:?values)?{<br />????result?=?result.add(nullToString(value));<br />}<br />
  7. 使用 Streams.filter (Java 8+)
  Stream API 是 Java 8 引入的功能強大的流式操作類(lèi),可以進(jìn)行常見(jiàn)的過(guò)濾、映射、遍歷、分組、統計等操作。其中的過(guò)濾操作 filter 可以接收一個(gè) Predicate 函數,Predicate 函數接口同之前介紹的 Function (opens new window)接口一樣,是一個(gè)函數式接口,它可以接受一個(gè)泛型 參數,返回值為布爾類(lèi)型,Predicate 常用于數據過(guò)濾。
  因此,我們可以定義一個(gè)Predicate 來(lái)檢查為 null 的字符串,然后傳遞給 Stream API 的 filter() 方法。
  最后再使用 Collectors.joining() 方法拼接剩余的非 null 字符串。
  String[]?values?=?{"https",?"://",?"www.",?"wdbyte",?".com",?null};<br />String?result?=?Arrays.stream(values)<br />????.filter(Objects::nonNull)<br />????.collect(Collectors.joining());<br />
  8. 總結
  這篇文章介紹了拼接非 null 字符串的幾種方式,不同的方式可能適合不同的場(chǎng)景,不過(guò)要注意拼接String 字符串是一項昂貴的操作,下面是使用 JMH 對幾種拼接方式進(jìn)行基準測試的結果。
  Benchmark???????????????????Mode???Cnt???????Score????????Error??Units<br />StringConcat.operateAdd?????thrpt???25??13635005.992?±?549759.774??ops/s<br />StringConcat.String.concat??thrpt???25???7465193.417?±?667928.552??ops/s<br />StringConcat.StringBuilder??thrpt???25??13949781.608?±?142001.421??ops/s<br />StringConcat.StringJoiner???thrpt???25???9502405.473?±?211977.433??ops/s<br />StringConcat.StreamFilter???thrpt???25???8998396.107?±?649033.722??ops/s<br />
  可以看到 StringBuilder 的性能是最好的,實(shí)際使用時(shí)要結合具體場(chǎng)景,然后選擇最低的性能開(kāi)銷(xiāo)方式。
  <p data-darkmode-bgcolor="rgb(36, 36, 36)" data-darkmode-original-bgcolor="rgb(255, 255, 255)" data-darkmode-color="rgb(106, 104, 111)" data-darkmode-original-color="rgb(106, 104, 111)" data-darkmode-bgcolor-15923650965579="rgb(36, 36, 36)" data-darkmode-original-bgcolor-15923650965579="rgb(255, 255, 255)" data-darkmode-color-15923650965579="rgb(106, 104, 111)" data-darkmode-original-color-15923650965579="rgb(106, 104, 111)" style="margin-right: 0em;margin-left: 0em;outline: 0px;color: rgb(106, 104, 111);">1.?SQL優(yōu)化萬(wàn)能公式:5 大步驟 + 10 個(gè)案例
  2.?大型 SaaS 平臺產(chǎn)品架構設計
  3.?Spring Cloud 分布式日志采集方案,建議收藏!
  4.?POI 導出 Excel:字體顏色、行列自適應、鎖住、合并單元格、一文搞定……
  
  最近面試BAT,整理一份面試資料《Java面試BATJ通關(guān)手冊》,覆蓋了Java核心技術(shù)、JVM、Java并發(fā)、SSM、微服務(wù)、數據庫、數據結構等等。
  獲取方式:點(diǎn)“在看”,關(guān)注公眾號并回復?Java?領(lǐng)取,更多內容陸續奉上。</p>
  <p data-tool="mdnice編輯器" style="margin-top: 10px;margin-bottom: 10px;padding-top: 8px;padding-bottom: 8px;outline: 0px;white-space: normal;font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;text-align: right;line-height: 1.6;color: rgb(63, 63, 63);">PS:因公眾號平臺更改了推送規則,如果不想錯過(guò)內容,記得讀完點(diǎn)一下“在看”,加個(gè)“星標”,這樣每次新文章推送才會(huì )第一時(shí)間出現在你的訂閱列表里。
  點(diǎn)“在看”支持小哈呀,謝謝啦<strong style="outline: 0px;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;color: rgb(0, 128, 255);font-size: 15px;"></strong></p>

數據治理 | 數據分析與清洗工具:Pandas 數據類(lèi)型轉換(贈送本文同款數據!

采集交流 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 116 次瀏覽 ? 2022-05-01 09:11 ? 來(lái)自相關(guān)話(huà)題

  數據治理 | 數據分析與清洗工具:Pandas 數據類(lèi)型轉換(贈送本文同款數據!
  Part1前言上期文章中,我們介紹了數據中的各種類(lèi)型的缺失值以及如何處理這些缺失值;同時(shí)也介紹了常見(jiàn)的數據重復問(wèn)題并奉上了處理重復數據的方法。這些處理方法對大家的數據治理、數據分析工作都有著(zhù)至關(guān)重要的作用。本期文章將會(huì )繼續學(xué)習 Pandas 工具,學(xué)習如何轉換數據類(lèi)型。讀完本文后,靈活轉換數據類(lèi)型將不再是問(wèn)題!本文中所有 Python 代碼均在集成開(kāi)發(fā)環(huán)境 Visual Studio Code (VScode) 中使用交互式開(kāi)發(fā)環(huán)境 Jupyter Notebook 編寫(xiě)。Part2為什么需要做數據類(lèi)型轉換數據的含義與數據的類(lèi)型是息息相關(guān)的,正確的數據類(lèi)型能夠支撐數據含義的正確表示。當一些數據的類(lèi)型出現錯亂時(shí),它們的含義也會(huì )變得“詭異”。請看下面幾個(gè)例子:
  錯誤示范
  正確示范
  原因解析
  今年是 2022.0年
  今年是 2022 年
  2022 作為一個(gè)年份時(shí),應該保存為整數型或者字符型,而不是浮點(diǎn)型(小數型)數字 2022.0
  圓周率保留兩位小數的結果是3
  圓周率保留兩位小數的結果是 3.14
  圓周率保留兩位小數應該是浮點(diǎn)數 3.14,如果轉為整數型,其結果就會(huì )是 3
  1 + 1 = 11
  1 + 1 = 2
  1 + 1 = 11 實(shí)際上是字符串拼接,即 '1' + '1' 得到了 '11'
  [0, 1, 2] 的第一個(gè)元素是[
  [0, 1, 2] 的第一個(gè)元素是 0
  列表 [0, 1, 2] 被保存為字符型,它的真面目是 "[0, 1, 2]",這個(gè)字符串的第一個(gè)元素是 '[' 而不是 0
  我們早已經(jīng)知道,Python 中字符串是用英文引號引起來(lái)的,就像是 'Python',"Python"。你可能會(huì )覺(jué)得,既然如此,數字型數據和字符型數據不就不容易搞混了嗎?例如,數字 2022 和 字符串 "2022" ,很容易就能區分。然而,實(shí)際的情況卻是,容易搞混,很容易搞混!這是因為在 Pandas 中,所有字符數據前后的引號都不會(huì )顯示出來(lái),如果顯示出了引號,那么這些引號也是字符串中的字符。所以使用 Pandas 處理數據,為了避免類(lèi)似的情況出現,學(xué)習數據類(lèi)型轉換是非常有必要的。Part3類(lèi)型轉換大多數時(shí)候,數據中不同字段的數據類(lèi)型是不一定全都一樣;同一個(gè)字段中,數據的類(lèi)型是一般是一致的。所以進(jìn)行數據類(lèi)型轉換時(shí)不需要一個(gè)一個(gè)對數據值做類(lèi)型轉換,直接操作一個(gè)字段會(huì )更加方便。我們使用本期贈送的數據作為介紹 Pandas 的示例數據,使用 Excel 打開(kāi)數據【5G 產(chǎn)業(yè)全國各省市分年度專(zhuān)利申請、專(zhuān)利授權情況(2000-2019.9).xlsx】,如下圖所示:
  
  贈送的數據中沒(méi)有缺失值,其中值為數字的字段在 Excel 中是數字類(lèi)型;我們使用 Pandas 讀取 Excel 或者 csv 數據時(shí),系統會(huì )自動(dòng)地將每個(gè)字段讀取為合適的數據類(lèi)型。如果需要自定義一些(或者所有)字段的類(lèi)型,我們也可以自己指定每個(gè)字段的數據類(lèi)型(數據必須滿(mǎn)足指定類(lèi)型的格式,例如我們不可以將 “省份名” 字段設置為 整數型)。使用 Pandas 讀取這個(gè) Excel 數據,代碼和輸出如下:
  #?數據存儲的路徑<br />path?=?'./5G?產(chǎn)業(yè)全國各省市分年度專(zhuān)利申請、專(zhuān)利授權情況(2000-2019.9).xlsx'<br />#?這里指定字段的數據類(lèi)型<br />columns_type?=?{'年份':'str',?<br />????????????????'省份名':'str',?<br />????????????????'省份行政代碼':'int',?????????????????????????????????<br />????????????????'專(zhuān)利申請':'int',?<br />????????????????'專(zhuān)利授權':'int',?<br />????????????????'專(zhuān)利類(lèi)型':'str'}<br />#?dtype?參數用于指定字段的類(lèi)型,如果不需要特意指定字段的類(lèi)型,不使用?dtype?參數即可<br />data?=?pd.read_excel(path,?dtype=columns_type)<br />data<br />
  
  讀取數據后我們使用 Pandas 中的相關(guān)方法生成一個(gè)新的列,這一列中的數據是一個(gè)包含專(zhuān)利申請、專(zhuān)利授權和專(zhuān)利類(lèi)型的列表。操作代碼和新生成的數據如下:
  #?根據專(zhuān)利申請、專(zhuān)利授權和專(zhuān)利類(lèi)型三個(gè)字段得到一個(gè)新字段<br />data['列表']?=?data.apply(lambda?X:?[X['專(zhuān)利申請'],?X['專(zhuān)利授權'],?X['專(zhuān)利類(lèi)型']]?,axis=1)<br />data<br />
  
  將新生成的數據保存為 csv 文件后再讀取,讀取時(shí)我們故意將部分字段讀取為錯誤的類(lèi)型,隨后使用錯誤的數據來(lái)給大家演示如何進(jìn)行數據類(lèi)型的轉換。
  #?將剛剛新生成的數據保存為?csv?文件<br />#?參數 index=False 的含義是,不講數據索引寫(xiě)入 csv 文件中<br />data.to_csv('新數據.csv',?index=False)<br /><br />#?使用錯誤的字段類(lèi)型重新讀取數據<br />#?我們將年份讀取為浮點(diǎn)型(小數型),將專(zhuān)利申請讀取為字符型<br />wrong_type?=?{'年份':'float',???????????????????????????????????<br />??????????????'專(zhuān)利申請':'str'}<br />DATA?=?pd.read_csv('新數據.csv',?dtype=wrong_type)<br /><br />#?查看專(zhuān)利申請字段類(lèi)型<br />print(DATA.專(zhuān)利申請.dtype)??#?輸出:object,說(shuō)明該字段含有字符型數據<br />DATA<br />
  
  可以看到,“年份” 字段中所有的年份都變?yōu)樾敌?;通過(guò)代碼也判斷出 “專(zhuān)利申請” 字段不再是整數型,而是字符型,因為 DataFrame 中的字符型數據不會(huì )顯示兩端的引號,所以無(wú)法目測其類(lèi)型。那么這種內容為數字的字符型數據會(huì )給我們什么麻煩呢?假設我們需要使用 專(zhuān)利授權/ 專(zhuān)利申請 來(lái)計算專(zhuān)利授權率時(shí) ,會(huì )發(fā)現整數和字符之間無(wú)法運算。如果這兩個(gè)字段中的值的都是字符型,那么兩者只能進(jìn)行加法運算,例如:“45” + “8” == “458”,這恐怕更不是我們想要的結果。接下來(lái)我們使用數據類(lèi)型轉換的方法來(lái)糾正這些錯誤的數據。1使用 astype() 轉換基本類(lèi)型Pandas 專(zhuān)門(mén)為類(lèi)型轉換提供了一個(gè) astype() 方法,這個(gè)方法可以將數據類(lèi)型轉換為希望的類(lèi)型,既可以操作 Series,又可以操作 DataFrame,使用時(shí)只需要傳入轉換后的類(lèi)型即可。我們在往期的文章中提到過(guò),Pandas 中絕大多數涉及到數據修改的方法,他們都不會(huì )直接修改原始的數據,而是返回一個(gè)新的數據。astype()也是一樣的,默認返回一個(gè)新的數據。場(chǎng)景 1:將數據中的年份字段轉換為整數型
  #?將字段類(lèi)型由浮點(diǎn)型(小數型)轉換為整數型?int<br />#?返回一個(gè)新數據,調用該方法的是一個(gè)?Series,返回值也將是一個(gè)?Series<br />DATA['年份'].astype(int)<br />
  
  希望類(lèi)型轉換操作在原始數據中生效可以使用下面的代碼。
  #?將新生的數據重新賦值給原始數據即可<br />#?賦值操作不會(huì )返回任何值<br />DATA['年份']?=?DATA['年份'].astype(int)<br />#?輸出查看轉換后的數據<br />DATA<br />
  
  場(chǎng)景 2:將數據中所有內容轉換為字符型數據,轉換后的數據命名為ALL_STR
  #?將類(lèi)型轉換為字符型數據后的新數據命名為?ALL_STR<br />ALL_STR?=?DATA.astype(str)<br />#?查看新數據的信息<br />ALL_STR.info()<br />
  
  所有的字段類(lèi)型都變?yōu)?object,說(shuō)明所有字段中都含有字符型數據,操作生效。另外,當字段中存在無(wú)法轉換的數據值時(shí),可以指定參數 errors='ignore' 來(lái)忽略無(wú)法轉換的數據值。假如我們希望將所有字段都轉換為浮點(diǎn)型(小數型),但是字符型數據 “北京” 、“45”、“發(fā)明專(zhuān)利” 等字符型數據無(wú)法轉換為浮點(diǎn)型,我們則可以使用下面的代碼來(lái)轉換可以轉換的字段:
  #?指定參數?errors='ignore',忽略無(wú)法轉換的數據值<br />DATA.astype(float,?errors='ignore')<br />
  
  可以看到,除了一些字符型數據之外,其他的數字類(lèi)型數據都被轉換為浮點(diǎn)型(小數型)數據。同樣地,如果不進(jìn)行賦值操作,那么就會(huì )返回一個(gè)新的數據,而原始數據不會(huì )發(fā)生變化。2使用 eval() 轉換特殊類(lèi)型astype() 方法多用于浮點(diǎn)型 float、整數型 int 和 字符型 str 的轉換操作。當涉及到字符型轉化為列表,字典等 Python 的組合數據類(lèi)型時(shí),則需要使用 Python 自帶的方法 eval() 。該函數可以去掉字符串最外側的引號,并按照 Python 語(yǔ)句方式執行去掉引號后的字符內容。下面我們舉例介紹一下 eval() 的用法。
  #?對字符串?'12'?做轉換<br />eval('12')?????#?得到整數:12<br /><br />#?對字符串?'12.5'?做轉換<br />eval('12.5')???#?得到浮點(diǎn)數:12.5<br /><br />#?對字符串?'12+5'?做轉換<br />eval('12+5')???#?得到整數:17<br /><br />#?定義變量?a?后對字符串?'a'?做轉換<br />a?=?'20'<br />eval('a')??????#?得到 a 的值:20<br /><br />#?對字符串?"[11,12,'列表元素']"?做轉換<br />eval("[11,12,'列表元素']")?#?得到列表:[11, 12, '列表元素']<br /><br />#?定義變量?m,n?后對字符串?'[m,n,m-50]'?做轉換<br />m=100<br />n='某個(gè)字符串'<br />eval("[m,n,m-50]")??#?得到列表:[100, '某個(gè)字符串', 50]<br />
  根據上面的例子可以看出,eval() 確實(shí)可以去掉字符串最外側的引號,并按照 Python 語(yǔ)句方式執行去掉引號后的字符內容。這個(gè)方法不僅可以轉換列表形式的字符串,對諸如字典、元組以及集合等 Python 數據類(lèi)型形式的字符串,該方法依然可用。場(chǎng)景 3:將數據中“列表”字段轉換為 Python 列表類(lèi)型由于 eval() 方法操作的是字符串對象,一次只接受一個(gè)需要轉化的對象,當需要使用它來(lái)對 DataFrame 的一整個(gè)字段做轉換操作時(shí),需要借助循環(huán)或者其他的 Pandas 方法。
  #?輸出查看轉換之前"列表"字段最后一個(gè)值的類(lèi)型,原始的類(lèi)型為?str?型<br />print(type(DATA['列表'].values[-1]))<br />#?輸出:,確認是字符型<br /><br />#?方法 1:借助 for 循環(huán)<br />for?i?in?DATA.index:<br />????#?遍歷數據的索引<br />????#?根據索引找到待轉換的數據<br />????Target?=?DATA.loc[i,'列表']<br />????#?將轉換后的數據重新賦值給原來(lái)位置的數據值<br />????DATA['列表'][i]?=?eval(Target)<br />????<br />#?輸出查看"列表"字段最后一個(gè)值的類(lèi)型,若為列表,說(shuō)明轉換成功<br />print(type(DATA['列表'].values[-1]))<br />#?輸出:,轉換成功<br /><br />#?方法 2:借助 Pandas 方法 map()。不再輸出查看類(lèi)型<br />DATA['列表']?=?DATA['列表'].map(eval)<br /><br />#?方法 3:借助 Pandas 方法 apply()。不再輸出查看類(lèi)型<br />DATA['列表']?=?DATA['列表'].apply(eval)<br />
  后面兩種方法可以實(shí)現 方法 1 同樣的效果,且代碼量更少。Part4總結本期文章中,我們介紹了數據類(lèi)型錯誤帶來(lái)的影響,同時(shí)也介紹了轉換字段數據類(lèi)型的方法。使用類(lèi)型轉換方法可以在基本的數據類(lèi)型之間進(jìn)行合理的轉換。同時(shí)也介紹了轉換特殊數據類(lèi)型的方法。學(xué)習這些可以讓我們靈活地轉換數據的類(lèi)型,避免類(lèi)型錯亂帶來(lái)的麻煩。在最后的 場(chǎng)景3中,我們使用了map() 和 apply() 兩個(gè)方法,使用更少的代碼完成了同樣的功能。下期文章我們將會(huì )繼續介紹 Pandas,學(xué)習如何使用以上兩種方法來(lái)根據已有的數據生成新的數據列(數據列衍生)。
   查看全部

  數據治理 | 數據分析與清洗工具:Pandas 數據類(lèi)型轉換(贈送本文同款數據!
  Part1前言上期文章中,我們介紹了數據中的各種類(lèi)型的缺失值以及如何處理這些缺失值;同時(shí)也介紹了常見(jiàn)的數據重復問(wèn)題并奉上了處理重復數據的方法。這些處理方法對大家的數據治理、數據分析工作都有著(zhù)至關(guān)重要的作用。本期文章將會(huì )繼續學(xué)習 Pandas 工具,學(xué)習如何轉換數據類(lèi)型。讀完本文后,靈活轉換數據類(lèi)型將不再是問(wèn)題!本文中所有 Python 代碼均在集成開(kāi)發(fā)環(huán)境 Visual Studio Code (VScode) 中使用交互式開(kāi)發(fā)環(huán)境 Jupyter Notebook 編寫(xiě)。Part2為什么需要做數據類(lèi)型轉換數據的含義與數據的類(lèi)型是息息相關(guān)的,正確的數據類(lèi)型能夠支撐數據含義的正確表示。當一些數據的類(lèi)型出現錯亂時(shí),它們的含義也會(huì )變得“詭異”。請看下面幾個(gè)例子:
  錯誤示范
  正確示范
  原因解析
  今年是 2022.0年
  今年是 2022 年
  2022 作為一個(gè)年份時(shí),應該保存為整數型或者字符型,而不是浮點(diǎn)型(小數型)數字 2022.0
  圓周率保留兩位小數的結果是3
  圓周率保留兩位小數的結果是 3.14
  圓周率保留兩位小數應該是浮點(diǎn)數 3.14,如果轉為整數型,其結果就會(huì )是 3
  1 + 1 = 11
  1 + 1 = 2
  1 + 1 = 11 實(shí)際上是字符串拼接,即 '1' + '1' 得到了 '11'
  [0, 1, 2] 的第一個(gè)元素是[
  [0, 1, 2] 的第一個(gè)元素是 0
  列表 [0, 1, 2] 被保存為字符型,它的真面目是 "[0, 1, 2]",這個(gè)字符串的第一個(gè)元素是 '[' 而不是 0
  我們早已經(jīng)知道,Python 中字符串是用英文引號引起來(lái)的,就像是 'Python',"Python"。你可能會(huì )覺(jué)得,既然如此,數字型數據和字符型數據不就不容易搞混了嗎?例如,數字 2022 和 字符串 "2022" ,很容易就能區分。然而,實(shí)際的情況卻是,容易搞混,很容易搞混!這是因為在 Pandas 中,所有字符數據前后的引號都不會(huì )顯示出來(lái),如果顯示出了引號,那么這些引號也是字符串中的字符。所以使用 Pandas 處理數據,為了避免類(lèi)似的情況出現,學(xué)習數據類(lèi)型轉換是非常有必要的。Part3類(lèi)型轉換大多數時(shí)候,數據中不同字段的數據類(lèi)型是不一定全都一樣;同一個(gè)字段中,數據的類(lèi)型是一般是一致的。所以進(jìn)行數據類(lèi)型轉換時(shí)不需要一個(gè)一個(gè)對數據值做類(lèi)型轉換,直接操作一個(gè)字段會(huì )更加方便。我們使用本期贈送的數據作為介紹 Pandas 的示例數據,使用 Excel 打開(kāi)數據【5G 產(chǎn)業(yè)全國各省市分年度專(zhuān)利申請、專(zhuān)利授權情況(2000-2019.9).xlsx】,如下圖所示:
  
  贈送的數據中沒(méi)有缺失值,其中值為數字的字段在 Excel 中是數字類(lèi)型;我們使用 Pandas 讀取 Excel 或者 csv 數據時(shí),系統會(huì )自動(dòng)地將每個(gè)字段讀取為合適的數據類(lèi)型。如果需要自定義一些(或者所有)字段的類(lèi)型,我們也可以自己指定每個(gè)字段的數據類(lèi)型(數據必須滿(mǎn)足指定類(lèi)型的格式,例如我們不可以將 “省份名” 字段設置為 整數型)。使用 Pandas 讀取這個(gè) Excel 數據,代碼和輸出如下:
  #?數據存儲的路徑<br />path?=?'./5G?產(chǎn)業(yè)全國各省市分年度專(zhuān)利申請、專(zhuān)利授權情況(2000-2019.9).xlsx'<br />#?這里指定字段的數據類(lèi)型<br />columns_type?=?{'年份':'str',?<br />????????????????'省份名':'str',?<br />????????????????'省份行政代碼':'int',?????????????????????????????????<br />????????????????'專(zhuān)利申請':'int',?<br />????????????????'專(zhuān)利授權':'int',?<br />????????????????'專(zhuān)利類(lèi)型':'str'}<br />#?dtype?參數用于指定字段的類(lèi)型,如果不需要特意指定字段的類(lèi)型,不使用?dtype?參數即可<br />data?=?pd.read_excel(path,?dtype=columns_type)<br />data<br />
  
  讀取數據后我們使用 Pandas 中的相關(guān)方法生成一個(gè)新的列,這一列中的數據是一個(gè)包含專(zhuān)利申請、專(zhuān)利授權和專(zhuān)利類(lèi)型的列表。操作代碼和新生成的數據如下:
  #?根據專(zhuān)利申請、專(zhuān)利授權和專(zhuān)利類(lèi)型三個(gè)字段得到一個(gè)新字段<br />data['列表']?=?data.apply(lambda?X:?[X['專(zhuān)利申請'],?X['專(zhuān)利授權'],?X['專(zhuān)利類(lèi)型']]?,axis=1)<br />data<br />
  
  將新生成的數據保存為 csv 文件后再讀取,讀取時(shí)我們故意將部分字段讀取為錯誤的類(lèi)型,隨后使用錯誤的數據來(lái)給大家演示如何進(jìn)行數據類(lèi)型的轉換。
  #?將剛剛新生成的數據保存為?csv?文件<br />#?參數 index=False 的含義是,不講數據索引寫(xiě)入 csv 文件中<br />data.to_csv('新數據.csv',?index=False)<br /><br />#?使用錯誤的字段類(lèi)型重新讀取數據<br />#?我們將年份讀取為浮點(diǎn)型(小數型),將專(zhuān)利申請讀取為字符型<br />wrong_type?=?{'年份':'float',???????????????????????????????????<br />??????????????'專(zhuān)利申請':'str'}<br />DATA?=?pd.read_csv('新數據.csv',?dtype=wrong_type)<br /><br />#?查看專(zhuān)利申請字段類(lèi)型<br />print(DATA.專(zhuān)利申請.dtype)??#?輸出:object,說(shuō)明該字段含有字符型數據<br />DATA<br />
  
  可以看到,“年份” 字段中所有的年份都變?yōu)樾敌?;通過(guò)代碼也判斷出 “專(zhuān)利申請” 字段不再是整數型,而是字符型,因為 DataFrame 中的字符型數據不會(huì )顯示兩端的引號,所以無(wú)法目測其類(lèi)型。那么這種內容為數字的字符型數據會(huì )給我們什么麻煩呢?假設我們需要使用 專(zhuān)利授權/ 專(zhuān)利申請 來(lái)計算專(zhuān)利授權率時(shí) ,會(huì )發(fā)現整數和字符之間無(wú)法運算。如果這兩個(gè)字段中的值的都是字符型,那么兩者只能進(jìn)行加法運算,例如:“45” + “8” == “458”,這恐怕更不是我們想要的結果。接下來(lái)我們使用數據類(lèi)型轉換的方法來(lái)糾正這些錯誤的數據。1使用 astype() 轉換基本類(lèi)型Pandas 專(zhuān)門(mén)為類(lèi)型轉換提供了一個(gè) astype() 方法,這個(gè)方法可以將數據類(lèi)型轉換為希望的類(lèi)型,既可以操作 Series,又可以操作 DataFrame,使用時(shí)只需要傳入轉換后的類(lèi)型即可。我們在往期的文章中提到過(guò),Pandas 中絕大多數涉及到數據修改的方法,他們都不會(huì )直接修改原始的數據,而是返回一個(gè)新的數據。astype()也是一樣的,默認返回一個(gè)新的數據。場(chǎng)景 1:將數據中的年份字段轉換為整數型
  #?將字段類(lèi)型由浮點(diǎn)型(小數型)轉換為整數型?int<br />#?返回一個(gè)新數據,調用該方法的是一個(gè)?Series,返回值也將是一個(gè)?Series<br />DATA['年份'].astype(int)<br />
  
  希望類(lèi)型轉換操作在原始數據中生效可以使用下面的代碼。
  #?將新生的數據重新賦值給原始數據即可<br />#?賦值操作不會(huì )返回任何值<br />DATA['年份']?=?DATA['年份'].astype(int)<br />#?輸出查看轉換后的數據<br />DATA<br />
  
  場(chǎng)景 2:將數據中所有內容轉換為字符型數據,轉換后的數據命名為ALL_STR
  #?將類(lèi)型轉換為字符型數據后的新數據命名為?ALL_STR<br />ALL_STR?=?DATA.astype(str)<br />#?查看新數據的信息<br />ALL_STR.info()<br />
  
  所有的字段類(lèi)型都變?yōu)?object,說(shuō)明所有字段中都含有字符型數據,操作生效。另外,當字段中存在無(wú)法轉換的數據值時(shí),可以指定參數 errors='ignore' 來(lái)忽略無(wú)法轉換的數據值。假如我們希望將所有字段都轉換為浮點(diǎn)型(小數型),但是字符型數據 “北京” 、“45”、“發(fā)明專(zhuān)利” 等字符型數據無(wú)法轉換為浮點(diǎn)型,我們則可以使用下面的代碼來(lái)轉換可以轉換的字段:
  #?指定參數?errors='ignore',忽略無(wú)法轉換的數據值<br />DATA.astype(float,?errors='ignore')<br />
  
  可以看到,除了一些字符型數據之外,其他的數字類(lèi)型數據都被轉換為浮點(diǎn)型(小數型)數據。同樣地,如果不進(jìn)行賦值操作,那么就會(huì )返回一個(gè)新的數據,而原始數據不會(huì )發(fā)生變化。2使用 eval() 轉換特殊類(lèi)型astype() 方法多用于浮點(diǎn)型 float、整數型 int 和 字符型 str 的轉換操作。當涉及到字符型轉化為列表,字典等 Python 的組合數據類(lèi)型時(shí),則需要使用 Python 自帶的方法 eval() 。該函數可以去掉字符串最外側的引號,并按照 Python 語(yǔ)句方式執行去掉引號后的字符內容。下面我們舉例介紹一下 eval() 的用法。
  #?對字符串?'12'?做轉換<br />eval('12')?????#?得到整數:12<br /><br />#?對字符串?'12.5'?做轉換<br />eval('12.5')???#?得到浮點(diǎn)數:12.5<br /><br />#?對字符串?'12+5'?做轉換<br />eval('12+5')???#?得到整數:17<br /><br />#?定義變量?a?后對字符串?'a'?做轉換<br />a?=?'20'<br />eval('a')??????#?得到 a 的值:20<br /><br />#?對字符串?"[11,12,'列表元素']"?做轉換<br />eval("[11,12,'列表元素']")?#?得到列表:[11, 12, '列表元素']<br /><br />#?定義變量?m,n?后對字符串?'[m,n,m-50]'?做轉換<br />m=100<br />n='某個(gè)字符串'<br />eval("[m,n,m-50]")??#?得到列表:[100, '某個(gè)字符串', 50]<br />
  根據上面的例子可以看出,eval() 確實(shí)可以去掉字符串最外側的引號,并按照 Python 語(yǔ)句方式執行去掉引號后的字符內容。這個(gè)方法不僅可以轉換列表形式的字符串,對諸如字典、元組以及集合等 Python 數據類(lèi)型形式的字符串,該方法依然可用。場(chǎng)景 3:將數據中“列表”字段轉換為 Python 列表類(lèi)型由于 eval() 方法操作的是字符串對象,一次只接受一個(gè)需要轉化的對象,當需要使用它來(lái)對 DataFrame 的一整個(gè)字段做轉換操作時(shí),需要借助循環(huán)或者其他的 Pandas 方法。
  #?輸出查看轉換之前"列表"字段最后一個(gè)值的類(lèi)型,原始的類(lèi)型為?str?型<br />print(type(DATA['列表'].values[-1]))<br />#?輸出:,確認是字符型<br /><br />#?方法 1:借助 for 循環(huán)<br />for?i?in?DATA.index:<br />????#?遍歷數據的索引<br />????#?根據索引找到待轉換的數據<br />????Target?=?DATA.loc[i,'列表']<br />????#?將轉換后的數據重新賦值給原來(lái)位置的數據值<br />????DATA['列表'][i]?=?eval(Target)<br />????<br />#?輸出查看"列表"字段最后一個(gè)值的類(lèi)型,若為列表,說(shuō)明轉換成功<br />print(type(DATA['列表'].values[-1]))<br />#?輸出:,轉換成功<br /><br />#?方法 2:借助 Pandas 方法 map()。不再輸出查看類(lèi)型<br />DATA['列表']?=?DATA['列表'].map(eval)<br /><br />#?方法 3:借助 Pandas 方法 apply()。不再輸出查看類(lèi)型<br />DATA['列表']?=?DATA['列表'].apply(eval)<br />
  后面兩種方法可以實(shí)現 方法 1 同樣的效果,且代碼量更少。Part4總結本期文章中,我們介紹了數據類(lèi)型錯誤帶來(lái)的影響,同時(shí)也介紹了轉換字段數據類(lèi)型的方法。使用類(lèi)型轉換方法可以在基本的數據類(lèi)型之間進(jìn)行合理的轉換。同時(shí)也介紹了轉換特殊數據類(lèi)型的方法。學(xué)習這些可以讓我們靈活地轉換數據的類(lèi)型,避免類(lèi)型錯亂帶來(lái)的麻煩。在最后的 場(chǎng)景3中,我們使用了map() 和 apply() 兩個(gè)方法,使用更少的代碼完成了同樣的功能。下期文章我們將會(huì )繼續介紹 Pandas,學(xué)習如何使用以上兩種方法來(lái)根據已有的數據生成新的數據列(數據列衍生)。
  

Crack App | 某搜索 App 中關(guān)于 x 信文章檢索功能的加密參數

采集交流 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 123 次瀏覽 ? 2022-04-30 02:25 ? 來(lái)自相關(guān)話(huà)題

  Crack App | 某搜索 App 中關(guān)于 x 信文章檢索功能的加密參數
  點(diǎn)擊上方“咸魚(yú)學(xué)Python”,選擇“加為星標”
  第一時(shí)間關(guān)注Python技術(shù)干貨!
  
  圖源:極簡(jiǎn)壁紙
  今日目標
  今天的目標是很多讀者朋友在采集微信文章時(shí)常用站的 app 版本
  aHR0cHM6Ly93d3cud2FuZG91amlhLmNvbS9zZWFyY2gvNjU1NTQ3NDYwMzMwMTAyMDk0MQ==
  抓包分析
  抓包使用的是 Charles + Postern 的組合
  使用大黃鳥(niǎo) app 抓包也是可以的,Charles 看著(zhù)會(huì )更舒服一些
  打開(kāi) app 搜索任意內容,切換到微信欄目就可以抓到以下的請求包了
  
  點(diǎn)擊這個(gè)請求可以看到請求參數還有請求的結果都是加密的
  
  請求的參數是k、v、u、r、g、p的名字,所以通過(guò)參數名檢索的方法很難定位到很準確的結果
  靜態(tài)分析定位邏輯
  apk 包推薦使用 jadx 1.2 打開(kāi),用 1.3 搜索的時(shí)候老是崩潰
  通過(guò)以請求鏈接的部分v2.get作為搜索關(guān)鍵詞可以定位到下面的搜索結果
  
  最后一個(gè)搜索的結果和我們的請求鏈接最匹配
  點(diǎn)進(jìn)去可以看到下面的內容
  
  可以看到圖中紅框的部分應該是請求的部分,紅框下面是返回的部分
  分別經(jīng)過(guò)了encrypt和decrypt兩個(gè)方法
  先講講我是怎么確定是這兩個(gè)方法的
  紅框部分中定義了一個(gè)hashMap,通其中put了一個(gè)Content-Length,這個(gè)搞過(guò) js 逆向的都知道,這個(gè)是代表了請求提交內容的長(cháng)度
  這個(gè)長(cháng)度是通過(guò)encrypt.length得到的,而encrypt是通過(guò)ScEncryptWall.encrypt(str, str2, str3);得到的
  而返回部分的代碼是在判斷了f0.b得出的,在f0.b的判斷中有一關(guān)于response success的輸出,進(jìn)一步確認了我們的判斷
  所以這里的encrypt和decrypt兩個(gè)方法是分析的重點(diǎn)
  進(jìn)一步追進(jìn)去可以看到這兩個(gè)方法都是native方法,定義在libSCoreTools.so里面
  
  動(dòng)態(tài)調試確認邏輯
  既然是 native 方法,通過(guò) IDA 分析這幾個(gè)也是導出方法,這里 hook 的方法就很多了。
  
  我們直接用frida hook看下出入參看看是不是符合我們在上一部分的猜想
  先看encrypt
  function?hook_encrypt(){<br />????Java.perform(function?()?{<br />????????var?ScEncryptWall?=?Java.use('包名.類(lèi)名');<br />????????ScEncryptWall.encrypt.implementation?=?function?(str1,str2,str3)?{<br />????????????console.log('str1:?',?str1);<br />????????????console.log('str2:?',?str2);<br />????????????console.log('str3:?',?str3);<br />????????????var?res?=?this.encrypt(str1,?str2,?str3);<br />????????????console.log('res:?',?res);<br />????????????return?res;<br />????????}<br />????})<br />}<br />setImmediate(hook_encrypt)<br />
  
  通過(guò)hook可以得到以下結果
  str1?=?請求的?url<br />str2?=?請求提交的參數(明文)<br />str3?=?空<br />
  返回的結果就是加密好的參數了
  同樣的hook decrypt
  function?hook_decrypt(){<br />????Java.perform(function?()?{<br />????????var?ScEncryptWall?=?Java.use('包名.類(lèi)名');<br />????????ScEncryptWall.decrypt.implementation?=?function?(data)?{<br />????????????console.log('data:?',?data);<br />????????????var?res?=?this.decrypt(a);<br />????????????console.log('res:?',?Java.use('java.lang.String').$new(res));<br />????????????return?res;<br />????????}<br />????})<br />}<br />setImmediate(hook_decrypt)<br />
  打印結果如下
  
  參數是請求的返回值,解密的結果是列表頁(yè)的內容
  完事~,Python RPC 調用一下就可以爽爽的采集相關(guān)的文章了 查看全部

  Crack App | 某搜索 App 中關(guān)于 x 信文章檢索功能的加密參數
  點(diǎn)擊上方“咸魚(yú)學(xué)Python”,選擇“加為星標”
  第一時(shí)間關(guān)注Python技術(shù)干貨!
  
  圖源:極簡(jiǎn)壁紙
  今日目標
  今天的目標是很多讀者朋友在采集微信文章時(shí)常用站的 app 版本
  aHR0cHM6Ly93d3cud2FuZG91amlhLmNvbS9zZWFyY2gvNjU1NTQ3NDYwMzMwMTAyMDk0MQ==
  抓包分析
  抓包使用的是 Charles + Postern 的組合
  使用大黃鳥(niǎo) app 抓包也是可以的,Charles 看著(zhù)會(huì )更舒服一些
  打開(kāi) app 搜索任意內容,切換到微信欄目就可以抓到以下的請求包了
  
  點(diǎn)擊這個(gè)請求可以看到請求參數還有請求的結果都是加密的
  
  請求的參數是k、v、u、r、g、p的名字,所以通過(guò)參數名檢索的方法很難定位到很準確的結果
  靜態(tài)分析定位邏輯
  apk 包推薦使用 jadx 1.2 打開(kāi),用 1.3 搜索的時(shí)候老是崩潰
  通過(guò)以請求鏈接的部分v2.get作為搜索關(guān)鍵詞可以定位到下面的搜索結果
  
  最后一個(gè)搜索的結果和我們的請求鏈接最匹配
  點(diǎn)進(jìn)去可以看到下面的內容
  
  可以看到圖中紅框的部分應該是請求的部分,紅框下面是返回的部分
  分別經(jīng)過(guò)了encrypt和decrypt兩個(gè)方法
  先講講我是怎么確定是這兩個(gè)方法的
  紅框部分中定義了一個(gè)hashMap,通其中put了一個(gè)Content-Length,這個(gè)搞過(guò) js 逆向的都知道,這個(gè)是代表了請求提交內容的長(cháng)度
  這個(gè)長(cháng)度是通過(guò)encrypt.length得到的,而encrypt是通過(guò)ScEncryptWall.encrypt(str, str2, str3);得到的
  而返回部分的代碼是在判斷了f0.b得出的,在f0.b的判斷中有一關(guān)于response success的輸出,進(jìn)一步確認了我們的判斷
  所以這里的encrypt和decrypt兩個(gè)方法是分析的重點(diǎn)
  進(jìn)一步追進(jìn)去可以看到這兩個(gè)方法都是native方法,定義在libSCoreTools.so里面
  
  動(dòng)態(tài)調試確認邏輯
  既然是 native 方法,通過(guò) IDA 分析這幾個(gè)也是導出方法,這里 hook 的方法就很多了。
  
  我們直接用frida hook看下出入參看看是不是符合我們在上一部分的猜想
  先看encrypt
  function?hook_encrypt(){<br />????Java.perform(function?()?{<br />????????var?ScEncryptWall?=?Java.use('包名.類(lèi)名');<br />????????ScEncryptWall.encrypt.implementation?=?function?(str1,str2,str3)?{<br />????????????console.log('str1:?',?str1);<br />????????????console.log('str2:?',?str2);<br />????????????console.log('str3:?',?str3);<br />????????????var?res?=?this.encrypt(str1,?str2,?str3);<br />????????????console.log('res:?',?res);<br />????????????return?res;<br />????????}<br />????})<br />}<br />setImmediate(hook_encrypt)<br />
  
  通過(guò)hook可以得到以下結果
  str1?=?請求的?url<br />str2?=?請求提交的參數(明文)<br />str3?=?空<br />
  返回的結果就是加密好的參數了
  同樣的hook decrypt
  function?hook_decrypt(){<br />????Java.perform(function?()?{<br />????????var?ScEncryptWall?=?Java.use('包名.類(lèi)名');<br />????????ScEncryptWall.decrypt.implementation?=?function?(data)?{<br />????????????console.log('data:?',?data);<br />????????????var?res?=?this.decrypt(a);<br />????????????console.log('res:?',?Java.use('java.lang.String').$new(res));<br />????????????return?res;<br />????????}<br />????})<br />}<br />setImmediate(hook_decrypt)<br />
  打印結果如下
  
  參數是請求的返回值,解密的結果是列表頁(yè)的內容
  完事~,Python RPC 調用一下就可以爽爽的采集相關(guān)的文章了

微信公眾號視頻批量下載軟件--視頻批量下載的方法

采集交流 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 395 次瀏覽 ? 2022-04-29 14:13 ? 來(lái)自相關(guān)話(huà)題

  微信公眾號視頻批量下載軟件--視頻批量下載的方法
  大家好,這是余夫第 011篇原創(chuàng )文章,關(guān)注余夫持續分享實(shí)用軟件和各種實(shí)用資料,第一時(shí)間獲取更多的軟件和資料。
  注意本公眾號介紹的所有下載視頻的軟件,視頻下載的前提是你的視頻必須是已經(jīng)付費購買(mǎi)了課程或者是免費視頻,只有可以正常播放才能下載。
  微信公眾號的視頻分為兩種
  一種是自己上傳到微信公眾號里面的視頻,以我自己的公眾號視頻為例如下圖
  
  這種就是直接上傳到公眾號里面的原創(chuàng )視頻,這種視頻可以直接復制鏈接到瀏覽器里面通過(guò)插件可以直接下載。
  這個(gè)文章介紹的下載方法就可以實(shí)現單個(gè)下載
  視頻少的話(huà)可以用上面單個(gè)的一個(gè)一個(gè)的下載,那要是上百個(gè)視頻就需要使用批量下載了。
  
  
  這樣直接就可以批量下載速度很快100個(gè)視頻也就是幾分鐘的事。有需要下載的可以聯(lián)系我代下載。
  另外一種是調用的騰訊視頻的鏈接,如下面這種就是調用騰訊視頻。
  
  這種的可以直接復制鏈接到瀏覽器里面里面去播放,選擇分辨率高的來(lái)播放,idm的插件也可以直接識別到點(diǎn)擊下載就可以了。
  也可以批量采集鏈接復制到軟件里面來(lái)下載。使用爬蟲(chóng)插件直接批量獲取鏈接
  
  
  直接復制鏈接到軟件里面就可以實(shí)現批量下載了。
  
  這樣就把公眾號的視頻下載下來(lái)了。 音頻是樣的道理,文章也是可以下載,過(guò)2天講下文章怎么下載的。 查看全部

  微信公眾號視頻批量下載軟件--視頻批量下載的方法
  大家好,這是余夫第 011篇原創(chuàng )文章,關(guān)注余夫持續分享實(shí)用軟件和各種實(shí)用資料,第一時(shí)間獲取更多的軟件和資料。
  注意本公眾號介紹的所有下載視頻的軟件,視頻下載的前提是你的視頻必須是已經(jīng)付費購買(mǎi)了課程或者是免費視頻,只有可以正常播放才能下載。
  微信公眾號的視頻分為兩種
  一種是自己上傳到微信公眾號里面的視頻,以我自己的公眾號視頻為例如下圖
  
  這種就是直接上傳到公眾號里面的原創(chuàng )視頻,這種視頻可以直接復制鏈接到瀏覽器里面通過(guò)插件可以直接下載。
  這個(gè)文章介紹的下載方法就可以實(shí)現單個(gè)下載
  視頻少的話(huà)可以用上面單個(gè)的一個(gè)一個(gè)的下載,那要是上百個(gè)視頻就需要使用批量下載了。
  
  
  這樣直接就可以批量下載速度很快100個(gè)視頻也就是幾分鐘的事。有需要下載的可以聯(lián)系我代下載。
  另外一種是調用的騰訊視頻的鏈接,如下面這種就是調用騰訊視頻。
  
  這種的可以直接復制鏈接到瀏覽器里面里面去播放,選擇分辨率高的來(lái)播放,idm的插件也可以直接識別到點(diǎn)擊下載就可以了。
  也可以批量采集鏈接復制到軟件里面來(lái)下載。使用爬蟲(chóng)插件直接批量獲取鏈接
  
  
  直接復制鏈接到軟件里面就可以實(shí)現批量下載了。
  
  這樣就把公眾號的視頻下載下來(lái)了。 音頻是樣的道理,文章也是可以下載,過(guò)2天講下文章怎么下載的。

調用鏈追蹤系統在伴魚(yú):Opentelemetry最佳實(shí)踐案例分享

采集交流 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 111 次瀏覽 ? 2022-04-29 14:06 ? 來(lái)自相關(guān)話(huà)題

  調用鏈追蹤系統在伴魚(yú):Opentelemetry最佳實(shí)踐案例分享
  搭建可靠的鏈路追蹤系統
  在正式介紹前,簡(jiǎn)單交代一下背景:2015 年,在伴魚(yú)服務(wù)端起步之時(shí),技術(shù)團隊就做出統一使用 Go 語(yǔ)言的決定。這個(gè)決定的影響主要體現在:
  早期實(shí)踐對接 Jaeger
  2019 年,公司內部的微服務(wù)數量逐步增加,調用關(guān)系日趨復雜,工程師做性能分析、問(wèn)題排查的難度變大。這時(shí)亟需一套調用鏈追蹤系統幫助我們增強對服務(wù)端全貌的了解。經(jīng)過(guò)調研后,我們決定采用同樣基于 Go 語(yǔ)言搭建的、由 CNCF 孵化的項目Jaeger。當時(shí),服務(wù)的開(kāi)發(fā)和治理都尚未引入 context,不論進(jìn)程內部調用還是跨進(jìn)程調用,都沒(méi)有上下文傳遞。因此早期引入調用鏈追蹤的工作重心就落在了服務(wù)及服務(wù)治理框架的改造,包括:
  部署方面:測試環(huán)境采用 all-in-one,線(xiàn)上環(huán)境采用 direct-to-storage 方案。整個(gè)過(guò)程前后大約耗時(shí)一個(gè)月,我們在 2019 年 Q3 上線(xiàn)了第一版調用鏈追蹤系統。配合廣泛被采用的 prometheus + grafana 以及 ELK,我們在微服務(wù)群的可觀(guān)測性上終于湊齊了調用鏈 (traces)、日志 (logs) 和監控指標 (metrics) 三個(gè)要素。
  下圖是第一版調用鏈追蹤系統的數據上報通路示意圖。服務(wù)運行在容器中,通過(guò) opentracing 的 sdk 埋點(diǎn),Jaeger 的 go-sdk 上報到宿主機上的 Jaeger-agent,后者再將數據進(jìn)一步上報到 Jaeger-collector,最終將調用鏈數據寫(xiě)入 ES,建立索引,即圖中的 Jaeger backends。
  
  遇到的問(wèn)題
  Jaeger 支持三種采樣方式:
  調用鏈通路改造使用場(chǎng)景
  2020 年,我們不斷收到業(yè)務(wù)研發(fā)的反饋:能不能全量采集 trace?
  這促使我們開(kāi)始重新思考如何改進(jìn)調用鏈追蹤系統。我們做了一個(gè)簡(jiǎn)單的容量預估:目前 Jaeger 每天寫(xiě)入 ES 的數據量接近 100GB/天,如果要全量采集 trace 數據,保守假設平均每個(gè) HTTP API 服務(wù)的總 QPS 為 100,那么完整存下全量數據需要 10TB/天;樂(lè )觀(guān)假設 100 名服務(wù)器研發(fā)每人每天查看 1 條 trace,每條 trace 的平均大小為 1KB,則整體信噪比千萬(wàn)分之一??梢钥闯?,這件事情本身的 ROI 很低,考慮到未來(lái)業(yè)務(wù)會(huì )持續增長(cháng),存儲這些數據的價(jià)值也會(huì )繼續降低,因此全量采集的方案被放棄。退一步想:全量采集真的是本質(zhì)需求嗎?實(shí)際上并非如此,我們想要的其實(shí)是「有意思」的 trace 全采,「沒(méi)意思」的 trace 不采。
  根據 理論篇 中介紹的應用場(chǎng)景,實(shí)際上第一版調用鏈追蹤系統只支持了穩態(tài)分析,而業(yè)務(wù)研發(fā)亟需的是異常檢測。要同時(shí)支持這兩種場(chǎng)景,我們必須借助尾部連貫采樣 (tail-based coherent sampling)。相對于頭部連貫采樣在第一個(gè) span 處就做出是否采樣的決定,尾部連貫采樣可以讓我們在獲取 (接近) 完整的 trace 信息后再做出判斷。理想情況下,只要能合理地制定采樣的判斷邏輯,我們的調用鏈追蹤系統就能做到「有意思」的 trace 全采,「沒(méi)意思」的 trace 不采。
  架構設計
  Jaeger 團隊從 2017 年就開(kāi)始討論引入 tail-based sampling 的可能性,但至今未有定論。在一次與 Jaeger 工程師 jpkrohling 的一對一溝通中,對方也證實(shí)了目前 Jaeger 尚沒(méi)有相關(guān)的支持計劃。因此,我們不得不另辟蹊徑。經(jīng)過(guò)一番調研,我們找到了剛剛進(jìn)駐 CNCF SandBox 的OpenTelemetry,它的opentelemetry-collector子項目恰好能支持我們在現有架構上引入尾部連貫采樣。
  OpenTelemetry Collector
  整個(gè) OpenTelemetry 項目目的在于統一市面上可觀(guān)測性數據 (telemetry data) 的標準,同時(shí)提供推動(dòng)這些標準實(shí)施的組件和工具。opentelemetry-collector 就是這個(gè)生態(tài)中的一個(gè)重要組件,它的架構圖如下:
  
  collector 內部有 4 個(gè)核心組件:
  opentelemetry-collector 項目被拆成兩部分:主項目 opentelemetry-collector 和社區貢獻項目 opentelemetry-collector-contrib,前者負責管理核心邏輯、數據結構以及通用的 Receivers、Processors、Exporters、Extensions 實(shí)現,后者則負責接收一些社區貢獻的組件,當然貢獻者主要都來(lái)自于可觀(guān)測性 SaaS 解決方案供應商,如 DataDog、Splunk、LightStep 以及一些公有云廠(chǎng)商。opentelemtry-collector 項目的插件化管理方式,使得定制化開(kāi)發(fā) Receiver、Processor、Exporter 的成本很低,我們在做概念驗證時(shí),基本可以在一兩個(gè)小時(shí)內開(kāi)發(fā)并測試完畢一個(gè)組件。除此之外,opentelemetry-collector-contrib 還提供了開(kāi)箱即用的tailsamplingprocessor。
  由于 opentelemetry-collector 是 OpenTelemetry 團隊推動(dòng)標準實(shí)施的重要組件,且 OpenTelemetry 本身并沒(méi)有提供獨立的數據存儲、索引實(shí)現的計劃,因此它在與市面上流行的調用鏈追蹤框架,如 Zipkin、Jaeger、OpenCensus,的兼容性上下了很大功夫。通過(guò) Receivers 和 Exporters 的使用,我們可以用它替換 jaeger-agent,也可以放在 jaeger-agent 與 jaeger-collector 之間,必要時(shí)還可以在 jaeger-agent 和 jaeger-collector 之間部署多層 collectors。除此之外,如果有一天想換掉 jaeger-backend,比如新發(fā)布的 Grafana Tempo,我們也能很輕松的完成,并且利用多個(gè) Pipelines 或一個(gè) Pipeline 多個(gè) Exporters 灰度上線(xiàn),逐步替換。
  上報通路
  基于以上的調研和現有的架構,我們設計了第二版調用鏈追蹤的架構,如下圖所示:
  
  用一組 opentelemetry-collector 替換 jaeger-agent,即圖中的 otel-agent;同時(shí)在 otel-agent 與 jaeger-collector 之間增加另一組 opentelemetry-collector,即圖中的 otel-collector。otel-agent 收集宿主機上不同服務(wù)上報的 trace 數據,打包批量發(fā)送給 otel-collector,后者負責做尾部連貫采樣,將「有意思」的 trace 繼續輸出到原始架構中的 jaeger-collector,后者負責將數據投入 ElasticSearch 中,建立索引。
  這里還有一個(gè)問(wèn)題需要解決:整個(gè)架構做到高可用,勢必要部署多個(gè) otel-collector 實(shí)例,如果使用簡(jiǎn)單的負載均衡策略,不同 otel-agents、以及單個(gè) otel-agent 不同時(shí)刻上報的數據,可能被隨機上報到某個(gè) otel-collector 實(shí)例,這就意味著(zhù),同一個(gè) trace 的不同 spans 無(wú)法集中到同一個(gè) otel-collector 實(shí)例上,既會(huì )導致同一個(gè) trace 的不同 spans 的決定不一致,即不是連貫采樣;也會(huì )導致尾部采樣時(shí)提供判斷的數據不全。解決方案很簡(jiǎn)單:讓 otel-agent 按照 traceID 做負載均衡。
  在調研階段我們正好看到 opentelemetry-collector 社區也有此支持計劃,并且前面提到的工程師 jpkrohling 正在通過(guò)增加loadbalancingexporter解決它,雖然直接使用 bleeding edge 的版本有一定的風(fēng)險,我們還是決定嘗試。在概念驗證階段,我們也的確發(fā)現了新功能的若干問(wèn)題,但通過(guò)反饋的方式一一解決,最終獲得了可以按預期執行尾部連貫采樣的調用鏈追蹤系統。
  采樣規則
  尾部連貫采樣的數據通路已經(jīng)準備就緒,下一步就是確定和實(shí)施采樣規則。
  「有意思」的調用鏈
  什么是「有意思」的調用鏈?研發(fā)在分析、排障過(guò)程中想查詢(xún)的任何調用鏈就是「有意思」的調用鏈。但落實(shí)到代碼的必須是確定性的規則,根據日常排障經(jīng)驗,我們先確定了以下三種情形:
  滿(mǎn)足任意條件,就認為這個(gè)調用鏈「有意思」。在伴魚(yú),只要服務(wù)打印了 ERROR 級別的日志就會(huì )觸發(fā)報警,研發(fā)人員就會(huì )收到 im 消息或電話(huà)報警,如果能保證觸發(fā)報警的調用鏈數據必采,研發(fā)人員的排障體驗就會(huì )有很大的提升;我們的 DBA 團隊認為超過(guò) 200ms 的查詢(xún)請求都被判定為慢查詢(xún),如果能保證這些請求的調用鏈必采,就能大大方便研發(fā)排查導致慢查詢(xún)的請求;對于在線(xiàn)服務(wù)來(lái)說(shuō),時(shí)延過(guò)高會(huì )令用戶(hù)體驗下降,但具體高到什么程度會(huì )引發(fā)明顯的體驗下降我們暫時(shí)沒(méi)有數據支撐,因此先配置為 1s,支持隨時(shí)修改閾值。
  當然,以上條件并不絕對,我們可以在之后的實(shí)踐根據反饋調整、新增規則,如單個(gè)請求引起的數據庫、緩存查詢(xún)次數超過(guò)某閾值等。
  采樣流水線(xiàn)
  在第二版系統中,我們期望同時(shí)支持穩態(tài)分析與異常檢測,因此采樣過(guò)程既要按概率或限流方式采集一部分 trace,也需要按上文擬定的「有意思」 規則采集令一部分 trace。截止到本文撰寫(xiě)前,tailsamplingprocessor支持 4 種策略:
  「按概率或限流采集一部分 trace」可以利用rate_limiting實(shí)現嗎?rate_limiting只能按照每秒通過(guò)的 spans 個(gè)數限流,但 spans 數量在高峰期、低峰期、業(yè)務(wù)所處階段都不一樣,每個(gè) trace 的平均 spans 數量也會(huì )隨著(zhù)微服務(wù)群規模以及依賴(lài)關(guān)系發(fā)生變化,因此設置 spans_per_second 將讓我們很難對這個(gè)參數的最終效果合理評估,因此直接使用rate_limiting的方案被否決。
  「按規則采集另一部分 trace」可以直接使用numeric_attribute和string_attribute實(shí)現嗎?span 中還存在布爾 (bool) 類(lèi)型的 tag,以「在調用鏈上如果打印了 ERROR 級別日志」為例,按照規范我們會(huì )記錄span.SetTag("error" , true),但 tailsamplingprocessor 并未支持bool_attribute;此外,未來(lái)我們可能會(huì )有更復雜的組合條件,這時(shí)僅靠numeric_attribute和string_attribute也無(wú)法實(shí)現。
  經(jīng)過(guò)再三分析,我們最終決定利用 Processors 的鏈式結構,組合多個(gè) Processor 完成采樣,流水線(xiàn)如下圖所示:
  
  其中probattr負責在 trace 級別按概率抽樣,anomaly 負責分析每個(gè) trace 是否符合「有意思」的規則,如果命中二者之一,trace 就會(huì )被打上標記,即sampling.priority。最后在tailsamplingprocessor上配置一條規則即可,如下所示:
  tail_sampling:<br />???policies:<br />?????[<br />???????{<br />?????????name:?sample_with_high_priority,<br />?????????type:?numeric_attribute,<br />?????????numeric_attribute:?{?key:?"sampling.priority",?min_value:?1,?max_value:?1?}<br />???????}<br />?????]
  這里sampling.priority是整數類(lèi)型,當前取值只有 0 和 1。按上面的配置,所以sampling.priority = 1的trace 都會(huì )被采集。后期可以增加更多的采集優(yōu)先級,在必要的時(shí)候可以多采樣 (upsampling) 或降采樣 (downsampling)。
  部署實(shí)施
  采樣規則確立后,整個(gè)解決方案就已跑通,下一步就是進(jìn)入部署實(shí)施階段。
  上線(xiàn)準備基礎庫改造
  動(dòng)態(tài)更新 Tracer在第一版系統中,每個(gè)進(jìn)程啟動(dòng)時(shí)會(huì )從 apollo 上獲取采樣配置,傳遞給 Jaeger sdk,后者利用配置初始化 GlobalTracer。GlobalTracer 會(huì )在 trace 的第一個(gè) span 出現時(shí),決定是否采集,并把這個(gè)決定傳遞下去,即頭部連貫采樣。在實(shí)施新架構時(shí),我們需要 Jaeger sdk 將所有 trace 數據盡數上報。為了讓這個(gè)過(guò)程更加平滑,我們對 Jaeger sdk 配置做出兩方面改造:
  支持對每個(gè)服務(wù)下發(fā)不同的采樣配置,方便灰度發(fā)布 支持動(dòng)態(tài)更新采樣配置,使采樣策略配置不依賴(lài)發(fā)布
  日志庫改造為了保證打印過(guò) ERROR 級別日志的調用鏈必采,我們也在通用日志庫的相應位置上給 span 打上 error 標簽。
  監控看板配置
  opentelemetry-collector 內部利用 OpenCensus sdk 埋了很多有用的監控指標,并按照 Open Metrics 規范暴露數據。因為指標數量并不多,我們將大多數指標都配置了到 Grafana 看板中,包括:
  xxx_receiver_accepted/refused_spans這里的 xxx 指代任意一個(gè) pipeline 中使用的 receiver。實(shí)際上這里有兩個(gè)具體指標:receiver 接收的 spans 數量和 receiver 拒絕的 spans 數量。二者可以與其它指標結合,分析系統在當前狀況下的入口流量瓶頸。
  xxx_exporter_send(failed)_spans這里的 xxx 指代任意一個(gè) pipeline 中使用的 exporter。實(shí)際上這里有兩個(gè)具體指標:exporter 發(fā)送成功的 spans 數量和 exporter 發(fā)送失敗的 spans 數量。二者可以與其它指標結合,分析系統在當前狀況下的出口流量瓶頸。
  otelcol_processor_tail_sampling_sampling_trace_dropped_too_early要介紹上面這個(gè)指標,需要簡(jiǎn)單了解tailsamplingprocessor的工作原理。在分布式環(huán)境中,tailsamplingprocessor永遠無(wú)法確定一個(gè) trace 的所有 spans 在當前時(shí)刻是否收集完畢,因此需要設置一個(gè)超時(shí)時(shí)間,即 這里 的decision_wait,下面假設decision_wait = 5s。Trace Data 進(jìn)入 processor 后,會(huì )被分別放入兩個(gè)數據結構:
  
  一個(gè)固定大小的隊列和一個(gè)哈希表,二者合起來(lái)實(shí)現 trace data 的 LRU cache。同時(shí) processor 會(huì )將所有進(jìn)入到其中的 traces 按照每秒一個(gè) batch 組織起來(lái),內部一共維持 5 個(gè) batch (decision_wait)。每隔一秒鐘,將最老的 batch 取出來(lái),對其中的 traces 分別判斷是否符合采樣規則,符合則將其傳遞給后續的 processors:
  
  如果在做采樣決策時(shí),發(fā)現相應的 trace 已經(jīng)被 LRU cache 清出,則認為「trace dropped too early」,后者意味著(zhù)tailsamplingprocessor已經(jīng)超負荷。理論上這個(gè)指標如果不等于 0,尾部連貫采樣功能就處于異常狀態(tài)。
  灰度方案
  上文提到過(guò),實(shí)施改造需要讓 Jaeger sdk 全量上報 trace。由于「是否上報」這個(gè)決定在請求入口服務(wù) (即 HTTP 服務(wù)) 做出,并會(huì )隨著(zhù)跨進(jìn)程調用傳播到下游服務(wù),同時(shí)伴魚(yú)服務(wù)端內部的入口服務(wù)已經(jīng)按照業(yè)務(wù)拆分,因此灰度的過(guò)程就可以按入口服務(wù)進(jìn)行,從流量小的、級別低入口服務(wù)開(kāi)始上線(xiàn)觀(guān)察,再逐漸加入流量大的、級別高的入口服務(wù),最終默認打開(kāi)全量采樣,并在這個(gè)過(guò)程中發(fā)現、解決潛在問(wèn)題。
  資源消耗優(yōu)化
  新版架構所需資源與舊版差別不大:
  在逐步上線(xiàn)到所有入口服務(wù)之前,我們做了比較充分的風(fēng)險評估。開(kāi)啟全量采集后,主要增加了宿主機的網(wǎng)絡(luò ) i/o,在千兆網(wǎng)卡 (約 300MB/s) 支持下,增加后的 i/o 量遠遠未達到瓶頸。實(shí)施過(guò)程中,業(yè)務(wù)團隊也確實(shí)沒(méi)有感知。不過(guò)在灰度上線(xiàn)過(guò)程中,我們也發(fā)現并解決了若干問(wèn)題。
  熱點(diǎn)服務(wù)問(wèn)題
  不同服務(wù)的請求量不同。個(gè)別服務(wù)的上報量過(guò)大會(huì )導致不同 otel-agent 的流量不均衡,在高峰期造成 otel-agent 的 CPU 經(jīng)常超過(guò)預警線(xiàn)。我們通過(guò)增加熱點(diǎn)服務(wù)實(shí)例,減小單個(gè)實(shí)例的請求量的方式,間接地均衡了每個(gè) otel-agent 承載的流量。
  過(guò)濾下推
  在生產(chǎn)環(huán)境中,我們默認維持最近 7 天的 trace 數據。在分析 ES 中索引jaeger-span-* 的過(guò)程中,意料之中地,我們看到了 power law 的存在:
  
  仔細分析可以發(fā)現,50% 以上的 span 都屬于apolloConfigCenter.*。熟悉 apollo 的研發(fā)應該知道,通常 apollo sdk 會(huì )通過(guò)長(cháng)輪詢(xún)的方式從元數據中心拉取配置信息,并緩存到本地,而服務(wù)在應用層獲取配置都是通過(guò)本地緩存獲取。因此實(shí)際上這里的所有apolloConfigCenter.*只是本地訪(fǎng)問(wèn),而不是跨進(jìn)程調用,span 數據價(jià)值比較低,可以忽略。于是我們開(kāi)發(fā)了通過(guò)正則匹配 spanName 過(guò)濾 span 的 processor,并部署到 otel-agent 上,我們稱(chēng)之為過(guò)濾下推。部署上線(xiàn)后,ES 索引體積下降超過(guò) 50%,目前每天索引體積為 40-50 GB;otel-collector 和 otel-agent 的 CPU 消耗也降低了接近 50%。
  制定 SLO
  在伴魚(yú)服務(wù)端內,線(xiàn)上問(wèn)題排查的第一入口通常是 im 消息,報警平臺會(huì )將導致報警的 traceID 以及日志注入到消息中,并提供一個(gè)鏈接頁(yè)面,方便研發(fā)快速查看報警相關(guān)的調用鏈信息及其在整個(gè)調用鏈上每個(gè)服務(wù)打印的日志?;诖宋覀冎贫ㄐ掳嬲{用鏈追蹤系統的SLO:
  名稱(chēng)
  研發(fā)關(guān)心的 trace 數據采集成功率
  SLI 規范
  研發(fā)關(guān)心且被采集的 trace 個(gè)數/研發(fā)關(guān)心的 trace 個(gè)數
  SLI 實(shí)現
  包含 trace 數據的服務(wù)報警信息條數/服務(wù)報警信息條數
  查詢(xún)
  sum(alertmanager_alert_total{trace_exists="true"})/sum(alertmanager_alert_total)
  目標
  99%
  目前我們剛剛在報警平臺中支持此 SLI 的埋點(diǎn)。目前還有個(gè)別服務(wù)尚未升級相關(guān)依賴(lài),因此該指標尚不能反映所有服務(wù)的情況,我們會(huì )繼續推動(dòng)各服務(wù)全面升級,按照以上 SLO 來(lái)要求新版系統。
  總結
  借助開(kāi)源項目,我們得以通過(guò)花費極少的人力,解決當前伴魚(yú)內部調用鏈追蹤應用的穩態(tài)分析及異常檢測需求,同時(shí)也為開(kāi)源項目和社區做出微小的貢獻。調用鏈追蹤是可觀(guān)測性平臺的重要組件,未來(lái)我們將繼續把一些精力放在 telemetry data 的整合上,為研發(fā)提供更全面、一致的服務(wù)觀(guān)測分析體驗。
  介紹
  文章原創(chuàng )來(lái)自于伴魚(yú)技術(shù)團隊的鄭鶴。
  伴魚(yú)少兒英語(yǔ)是目前飛速成長(cháng)的互聯(lián)網(wǎng)在線(xiàn)英語(yǔ)教育品牌之一。我們期望打造更創(chuàng )新、更酷、讓學(xué)英語(yǔ)更有效的新一代互聯(lián)網(wǎng)產(chǎn)品。轉載:著(zhù)作權歸作者所有。商業(yè)轉載請聯(lián)系作者獲得授權,非商業(yè)轉載請注明出處。
  Hi,我是老蔣。這里是中國Opentelemetry官方開(kāi)源社區組織。我們定期分享精彩的Opentelemetry 落地案例,請大家持續關(guān)注
  
  參考 查看全部

  調用鏈追蹤系統在伴魚(yú):Opentelemetry最佳實(shí)踐案例分享
  搭建可靠的鏈路追蹤系統
  在正式介紹前,簡(jiǎn)單交代一下背景:2015 年,在伴魚(yú)服務(wù)端起步之時(shí),技術(shù)團隊就做出統一使用 Go 語(yǔ)言的決定。這個(gè)決定的影響主要體現在:
  早期實(shí)踐對接 Jaeger
  2019 年,公司內部的微服務(wù)數量逐步增加,調用關(guān)系日趨復雜,工程師做性能分析、問(wèn)題排查的難度變大。這時(shí)亟需一套調用鏈追蹤系統幫助我們增強對服務(wù)端全貌的了解。經(jīng)過(guò)調研后,我們決定采用同樣基于 Go 語(yǔ)言搭建的、由 CNCF 孵化的項目Jaeger。當時(shí),服務(wù)的開(kāi)發(fā)和治理都尚未引入 context,不論進(jìn)程內部調用還是跨進(jìn)程調用,都沒(méi)有上下文傳遞。因此早期引入調用鏈追蹤的工作重心就落在了服務(wù)及服務(wù)治理框架的改造,包括:
  部署方面:測試環(huán)境采用 all-in-one,線(xiàn)上環(huán)境采用 direct-to-storage 方案。整個(gè)過(guò)程前后大約耗時(shí)一個(gè)月,我們在 2019 年 Q3 上線(xiàn)了第一版調用鏈追蹤系統。配合廣泛被采用的 prometheus + grafana 以及 ELK,我們在微服務(wù)群的可觀(guān)測性上終于湊齊了調用鏈 (traces)、日志 (logs) 和監控指標 (metrics) 三個(gè)要素。
  下圖是第一版調用鏈追蹤系統的數據上報通路示意圖。服務(wù)運行在容器中,通過(guò) opentracing 的 sdk 埋點(diǎn),Jaeger 的 go-sdk 上報到宿主機上的 Jaeger-agent,后者再將數據進(jìn)一步上報到 Jaeger-collector,最終將調用鏈數據寫(xiě)入 ES,建立索引,即圖中的 Jaeger backends。
  
  遇到的問(wèn)題
  Jaeger 支持三種采樣方式:
  調用鏈通路改造使用場(chǎng)景
  2020 年,我們不斷收到業(yè)務(wù)研發(fā)的反饋:能不能全量采集 trace?
  這促使我們開(kāi)始重新思考如何改進(jìn)調用鏈追蹤系統。我們做了一個(gè)簡(jiǎn)單的容量預估:目前 Jaeger 每天寫(xiě)入 ES 的數據量接近 100GB/天,如果要全量采集 trace 數據,保守假設平均每個(gè) HTTP API 服務(wù)的總 QPS 為 100,那么完整存下全量數據需要 10TB/天;樂(lè )觀(guān)假設 100 名服務(wù)器研發(fā)每人每天查看 1 條 trace,每條 trace 的平均大小為 1KB,則整體信噪比千萬(wàn)分之一??梢钥闯?,這件事情本身的 ROI 很低,考慮到未來(lái)業(yè)務(wù)會(huì )持續增長(cháng),存儲這些數據的價(jià)值也會(huì )繼續降低,因此全量采集的方案被放棄。退一步想:全量采集真的是本質(zhì)需求嗎?實(shí)際上并非如此,我們想要的其實(shí)是「有意思」的 trace 全采,「沒(méi)意思」的 trace 不采。
  根據 理論篇 中介紹的應用場(chǎng)景,實(shí)際上第一版調用鏈追蹤系統只支持了穩態(tài)分析,而業(yè)務(wù)研發(fā)亟需的是異常檢測。要同時(shí)支持這兩種場(chǎng)景,我們必須借助尾部連貫采樣 (tail-based coherent sampling)。相對于頭部連貫采樣在第一個(gè) span 處就做出是否采樣的決定,尾部連貫采樣可以讓我們在獲取 (接近) 完整的 trace 信息后再做出判斷。理想情況下,只要能合理地制定采樣的判斷邏輯,我們的調用鏈追蹤系統就能做到「有意思」的 trace 全采,「沒(méi)意思」的 trace 不采。
  架構設計
  Jaeger 團隊從 2017 年就開(kāi)始討論引入 tail-based sampling 的可能性,但至今未有定論。在一次與 Jaeger 工程師 jpkrohling 的一對一溝通中,對方也證實(shí)了目前 Jaeger 尚沒(méi)有相關(guān)的支持計劃。因此,我們不得不另辟蹊徑。經(jīng)過(guò)一番調研,我們找到了剛剛進(jìn)駐 CNCF SandBox 的OpenTelemetry,它的opentelemetry-collector子項目恰好能支持我們在現有架構上引入尾部連貫采樣。
  OpenTelemetry Collector
  整個(gè) OpenTelemetry 項目目的在于統一市面上可觀(guān)測性數據 (telemetry data) 的標準,同時(shí)提供推動(dòng)這些標準實(shí)施的組件和工具。opentelemetry-collector 就是這個(gè)生態(tài)中的一個(gè)重要組件,它的架構圖如下:
  
  collector 內部有 4 個(gè)核心組件:
  opentelemetry-collector 項目被拆成兩部分:主項目 opentelemetry-collector 和社區貢獻項目 opentelemetry-collector-contrib,前者負責管理核心邏輯、數據結構以及通用的 Receivers、Processors、Exporters、Extensions 實(shí)現,后者則負責接收一些社區貢獻的組件,當然貢獻者主要都來(lái)自于可觀(guān)測性 SaaS 解決方案供應商,如 DataDog、Splunk、LightStep 以及一些公有云廠(chǎng)商。opentelemtry-collector 項目的插件化管理方式,使得定制化開(kāi)發(fā) Receiver、Processor、Exporter 的成本很低,我們在做概念驗證時(shí),基本可以在一兩個(gè)小時(shí)內開(kāi)發(fā)并測試完畢一個(gè)組件。除此之外,opentelemetry-collector-contrib 還提供了開(kāi)箱即用的tailsamplingprocessor。
  由于 opentelemetry-collector 是 OpenTelemetry 團隊推動(dòng)標準實(shí)施的重要組件,且 OpenTelemetry 本身并沒(méi)有提供獨立的數據存儲、索引實(shí)現的計劃,因此它在與市面上流行的調用鏈追蹤框架,如 Zipkin、Jaeger、OpenCensus,的兼容性上下了很大功夫。通過(guò) Receivers 和 Exporters 的使用,我們可以用它替換 jaeger-agent,也可以放在 jaeger-agent 與 jaeger-collector 之間,必要時(shí)還可以在 jaeger-agent 和 jaeger-collector 之間部署多層 collectors。除此之外,如果有一天想換掉 jaeger-backend,比如新發(fā)布的 Grafana Tempo,我們也能很輕松的完成,并且利用多個(gè) Pipelines 或一個(gè) Pipeline 多個(gè) Exporters 灰度上線(xiàn),逐步替換。
  上報通路
  基于以上的調研和現有的架構,我們設計了第二版調用鏈追蹤的架構,如下圖所示:
  
  用一組 opentelemetry-collector 替換 jaeger-agent,即圖中的 otel-agent;同時(shí)在 otel-agent 與 jaeger-collector 之間增加另一組 opentelemetry-collector,即圖中的 otel-collector。otel-agent 收集宿主機上不同服務(wù)上報的 trace 數據,打包批量發(fā)送給 otel-collector,后者負責做尾部連貫采樣,將「有意思」的 trace 繼續輸出到原始架構中的 jaeger-collector,后者負責將數據投入 ElasticSearch 中,建立索引。
  這里還有一個(gè)問(wèn)題需要解決:整個(gè)架構做到高可用,勢必要部署多個(gè) otel-collector 實(shí)例,如果使用簡(jiǎn)單的負載均衡策略,不同 otel-agents、以及單個(gè) otel-agent 不同時(shí)刻上報的數據,可能被隨機上報到某個(gè) otel-collector 實(shí)例,這就意味著(zhù),同一個(gè) trace 的不同 spans 無(wú)法集中到同一個(gè) otel-collector 實(shí)例上,既會(huì )導致同一個(gè) trace 的不同 spans 的決定不一致,即不是連貫采樣;也會(huì )導致尾部采樣時(shí)提供判斷的數據不全。解決方案很簡(jiǎn)單:讓 otel-agent 按照 traceID 做負載均衡。
  在調研階段我們正好看到 opentelemetry-collector 社區也有此支持計劃,并且前面提到的工程師 jpkrohling 正在通過(guò)增加loadbalancingexporter解決它,雖然直接使用 bleeding edge 的版本有一定的風(fēng)險,我們還是決定嘗試。在概念驗證階段,我們也的確發(fā)現了新功能的若干問(wèn)題,但通過(guò)反饋的方式一一解決,最終獲得了可以按預期執行尾部連貫采樣的調用鏈追蹤系統。
  采樣規則
  尾部連貫采樣的數據通路已經(jīng)準備就緒,下一步就是確定和實(shí)施采樣規則。
  「有意思」的調用鏈
  什么是「有意思」的調用鏈?研發(fā)在分析、排障過(guò)程中想查詢(xún)的任何調用鏈就是「有意思」的調用鏈。但落實(shí)到代碼的必須是確定性的規則,根據日常排障經(jīng)驗,我們先確定了以下三種情形:
  滿(mǎn)足任意條件,就認為這個(gè)調用鏈「有意思」。在伴魚(yú),只要服務(wù)打印了 ERROR 級別的日志就會(huì )觸發(fā)報警,研發(fā)人員就會(huì )收到 im 消息或電話(huà)報警,如果能保證觸發(fā)報警的調用鏈數據必采,研發(fā)人員的排障體驗就會(huì )有很大的提升;我們的 DBA 團隊認為超過(guò) 200ms 的查詢(xún)請求都被判定為慢查詢(xún),如果能保證這些請求的調用鏈必采,就能大大方便研發(fā)排查導致慢查詢(xún)的請求;對于在線(xiàn)服務(wù)來(lái)說(shuō),時(shí)延過(guò)高會(huì )令用戶(hù)體驗下降,但具體高到什么程度會(huì )引發(fā)明顯的體驗下降我們暫時(shí)沒(méi)有數據支撐,因此先配置為 1s,支持隨時(shí)修改閾值。
  當然,以上條件并不絕對,我們可以在之后的實(shí)踐根據反饋調整、新增規則,如單個(gè)請求引起的數據庫、緩存查詢(xún)次數超過(guò)某閾值等。
  采樣流水線(xiàn)
  在第二版系統中,我們期望同時(shí)支持穩態(tài)分析與異常檢測,因此采樣過(guò)程既要按概率或限流方式采集一部分 trace,也需要按上文擬定的「有意思」 規則采集令一部分 trace。截止到本文撰寫(xiě)前,tailsamplingprocessor支持 4 種策略:
  「按概率或限流采集一部分 trace」可以利用rate_limiting實(shí)現嗎?rate_limiting只能按照每秒通過(guò)的 spans 個(gè)數限流,但 spans 數量在高峰期、低峰期、業(yè)務(wù)所處階段都不一樣,每個(gè) trace 的平均 spans 數量也會(huì )隨著(zhù)微服務(wù)群規模以及依賴(lài)關(guān)系發(fā)生變化,因此設置 spans_per_second 將讓我們很難對這個(gè)參數的最終效果合理評估,因此直接使用rate_limiting的方案被否決。
  「按規則采集另一部分 trace」可以直接使用numeric_attribute和string_attribute實(shí)現嗎?span 中還存在布爾 (bool) 類(lèi)型的 tag,以「在調用鏈上如果打印了 ERROR 級別日志」為例,按照規范我們會(huì )記錄span.SetTag("error" , true),但 tailsamplingprocessor 并未支持bool_attribute;此外,未來(lái)我們可能會(huì )有更復雜的組合條件,這時(shí)僅靠numeric_attribute和string_attribute也無(wú)法實(shí)現。
  經(jīng)過(guò)再三分析,我們最終決定利用 Processors 的鏈式結構,組合多個(gè) Processor 完成采樣,流水線(xiàn)如下圖所示:
  
  其中probattr負責在 trace 級別按概率抽樣,anomaly 負責分析每個(gè) trace 是否符合「有意思」的規則,如果命中二者之一,trace 就會(huì )被打上標記,即sampling.priority。最后在tailsamplingprocessor上配置一條規則即可,如下所示:
  tail_sampling:<br />???policies:<br />?????[<br />???????{<br />?????????name:?sample_with_high_priority,<br />?????????type:?numeric_attribute,<br />?????????numeric_attribute:?{?key:?"sampling.priority",?min_value:?1,?max_value:?1?}<br />???????}<br />?????]
  這里sampling.priority是整數類(lèi)型,當前取值只有 0 和 1。按上面的配置,所以sampling.priority = 1的trace 都會(huì )被采集。后期可以增加更多的采集優(yōu)先級,在必要的時(shí)候可以多采樣 (upsampling) 或降采樣 (downsampling)。
  部署實(shí)施
  采樣規則確立后,整個(gè)解決方案就已跑通,下一步就是進(jìn)入部署實(shí)施階段。
  上線(xiàn)準備基礎庫改造
  動(dòng)態(tài)更新 Tracer在第一版系統中,每個(gè)進(jìn)程啟動(dòng)時(shí)會(huì )從 apollo 上獲取采樣配置,傳遞給 Jaeger sdk,后者利用配置初始化 GlobalTracer。GlobalTracer 會(huì )在 trace 的第一個(gè) span 出現時(shí),決定是否采集,并把這個(gè)決定傳遞下去,即頭部連貫采樣。在實(shí)施新架構時(shí),我們需要 Jaeger sdk 將所有 trace 數據盡數上報。為了讓這個(gè)過(guò)程更加平滑,我們對 Jaeger sdk 配置做出兩方面改造:
  支持對每個(gè)服務(wù)下發(fā)不同的采樣配置,方便灰度發(fā)布 支持動(dòng)態(tài)更新采樣配置,使采樣策略配置不依賴(lài)發(fā)布
  日志庫改造為了保證打印過(guò) ERROR 級別日志的調用鏈必采,我們也在通用日志庫的相應位置上給 span 打上 error 標簽。
  監控看板配置
  opentelemetry-collector 內部利用 OpenCensus sdk 埋了很多有用的監控指標,并按照 Open Metrics 規范暴露數據。因為指標數量并不多,我們將大多數指標都配置了到 Grafana 看板中,包括:
  xxx_receiver_accepted/refused_spans這里的 xxx 指代任意一個(gè) pipeline 中使用的 receiver。實(shí)際上這里有兩個(gè)具體指標:receiver 接收的 spans 數量和 receiver 拒絕的 spans 數量。二者可以與其它指標結合,分析系統在當前狀況下的入口流量瓶頸。
  xxx_exporter_send(failed)_spans這里的 xxx 指代任意一個(gè) pipeline 中使用的 exporter。實(shí)際上這里有兩個(gè)具體指標:exporter 發(fā)送成功的 spans 數量和 exporter 發(fā)送失敗的 spans 數量。二者可以與其它指標結合,分析系統在當前狀況下的出口流量瓶頸。
  otelcol_processor_tail_sampling_sampling_trace_dropped_too_early要介紹上面這個(gè)指標,需要簡(jiǎn)單了解tailsamplingprocessor的工作原理。在分布式環(huán)境中,tailsamplingprocessor永遠無(wú)法確定一個(gè) trace 的所有 spans 在當前時(shí)刻是否收集完畢,因此需要設置一個(gè)超時(shí)時(shí)間,即 這里 的decision_wait,下面假設decision_wait = 5s。Trace Data 進(jìn)入 processor 后,會(huì )被分別放入兩個(gè)數據結構:
  
  一個(gè)固定大小的隊列和一個(gè)哈希表,二者合起來(lái)實(shí)現 trace data 的 LRU cache。同時(shí) processor 會(huì )將所有進(jìn)入到其中的 traces 按照每秒一個(gè) batch 組織起來(lái),內部一共維持 5 個(gè) batch (decision_wait)。每隔一秒鐘,將最老的 batch 取出來(lái),對其中的 traces 分別判斷是否符合采樣規則,符合則將其傳遞給后續的 processors:
  
  如果在做采樣決策時(shí),發(fā)現相應的 trace 已經(jīng)被 LRU cache 清出,則認為「trace dropped too early」,后者意味著(zhù)tailsamplingprocessor已經(jīng)超負荷。理論上這個(gè)指標如果不等于 0,尾部連貫采樣功能就處于異常狀態(tài)。
  灰度方案
  上文提到過(guò),實(shí)施改造需要讓 Jaeger sdk 全量上報 trace。由于「是否上報」這個(gè)決定在請求入口服務(wù) (即 HTTP 服務(wù)) 做出,并會(huì )隨著(zhù)跨進(jìn)程調用傳播到下游服務(wù),同時(shí)伴魚(yú)服務(wù)端內部的入口服務(wù)已經(jīng)按照業(yè)務(wù)拆分,因此灰度的過(guò)程就可以按入口服務(wù)進(jìn)行,從流量小的、級別低入口服務(wù)開(kāi)始上線(xiàn)觀(guān)察,再逐漸加入流量大的、級別高的入口服務(wù),最終默認打開(kāi)全量采樣,并在這個(gè)過(guò)程中發(fā)現、解決潛在問(wèn)題。
  資源消耗優(yōu)化
  新版架構所需資源與舊版差別不大:
  在逐步上線(xiàn)到所有入口服務(wù)之前,我們做了比較充分的風(fēng)險評估。開(kāi)啟全量采集后,主要增加了宿主機的網(wǎng)絡(luò ) i/o,在千兆網(wǎng)卡 (約 300MB/s) 支持下,增加后的 i/o 量遠遠未達到瓶頸。實(shí)施過(guò)程中,業(yè)務(wù)團隊也確實(shí)沒(méi)有感知。不過(guò)在灰度上線(xiàn)過(guò)程中,我們也發(fā)現并解決了若干問(wèn)題。
  熱點(diǎn)服務(wù)問(wèn)題
  不同服務(wù)的請求量不同。個(gè)別服務(wù)的上報量過(guò)大會(huì )導致不同 otel-agent 的流量不均衡,在高峰期造成 otel-agent 的 CPU 經(jīng)常超過(guò)預警線(xiàn)。我們通過(guò)增加熱點(diǎn)服務(wù)實(shí)例,減小單個(gè)實(shí)例的請求量的方式,間接地均衡了每個(gè) otel-agent 承載的流量。
  過(guò)濾下推
  在生產(chǎn)環(huán)境中,我們默認維持最近 7 天的 trace 數據。在分析 ES 中索引jaeger-span-* 的過(guò)程中,意料之中地,我們看到了 power law 的存在:
  
  仔細分析可以發(fā)現,50% 以上的 span 都屬于apolloConfigCenter.*。熟悉 apollo 的研發(fā)應該知道,通常 apollo sdk 會(huì )通過(guò)長(cháng)輪詢(xún)的方式從元數據中心拉取配置信息,并緩存到本地,而服務(wù)在應用層獲取配置都是通過(guò)本地緩存獲取。因此實(shí)際上這里的所有apolloConfigCenter.*只是本地訪(fǎng)問(wèn),而不是跨進(jìn)程調用,span 數據價(jià)值比較低,可以忽略。于是我們開(kāi)發(fā)了通過(guò)正則匹配 spanName 過(guò)濾 span 的 processor,并部署到 otel-agent 上,我們稱(chēng)之為過(guò)濾下推。部署上線(xiàn)后,ES 索引體積下降超過(guò) 50%,目前每天索引體積為 40-50 GB;otel-collector 和 otel-agent 的 CPU 消耗也降低了接近 50%。
  制定 SLO
  在伴魚(yú)服務(wù)端內,線(xiàn)上問(wèn)題排查的第一入口通常是 im 消息,報警平臺會(huì )將導致報警的 traceID 以及日志注入到消息中,并提供一個(gè)鏈接頁(yè)面,方便研發(fā)快速查看報警相關(guān)的調用鏈信息及其在整個(gè)調用鏈上每個(gè)服務(wù)打印的日志?;诖宋覀冎贫ㄐ掳嬲{用鏈追蹤系統的SLO:
  名稱(chēng)
  研發(fā)關(guān)心的 trace 數據采集成功率
  SLI 規范
  研發(fā)關(guān)心且被采集的 trace 個(gè)數/研發(fā)關(guān)心的 trace 個(gè)數
  SLI 實(shí)現
  包含 trace 數據的服務(wù)報警信息條數/服務(wù)報警信息條數
  查詢(xún)
  sum(alertmanager_alert_total{trace_exists="true"})/sum(alertmanager_alert_total)
  目標
  99%
  目前我們剛剛在報警平臺中支持此 SLI 的埋點(diǎn)。目前還有個(gè)別服務(wù)尚未升級相關(guān)依賴(lài),因此該指標尚不能反映所有服務(wù)的情況,我們會(huì )繼續推動(dòng)各服務(wù)全面升級,按照以上 SLO 來(lái)要求新版系統。
  總結
  借助開(kāi)源項目,我們得以通過(guò)花費極少的人力,解決當前伴魚(yú)內部調用鏈追蹤應用的穩態(tài)分析及異常檢測需求,同時(shí)也為開(kāi)源項目和社區做出微小的貢獻。調用鏈追蹤是可觀(guān)測性平臺的重要組件,未來(lái)我們將繼續把一些精力放在 telemetry data 的整合上,為研發(fā)提供更全面、一致的服務(wù)觀(guān)測分析體驗。
  介紹
  文章原創(chuàng )來(lái)自于伴魚(yú)技術(shù)團隊的鄭鶴。
  伴魚(yú)少兒英語(yǔ)是目前飛速成長(cháng)的互聯(lián)網(wǎng)在線(xiàn)英語(yǔ)教育品牌之一。我們期望打造更創(chuàng )新、更酷、讓學(xué)英語(yǔ)更有效的新一代互聯(lián)網(wǎng)產(chǎn)品。轉載:著(zhù)作權歸作者所有。商業(yè)轉載請聯(lián)系作者獲得授權,非商業(yè)轉載請注明出處。
  Hi,我是老蔣。這里是中國Opentelemetry官方開(kāi)源社區組織。我們定期分享精彩的Opentelemetry 落地案例,請大家持續關(guān)注
  
  參考

文章采集調用(中國的股票市場(chǎng)上盈利,每周都有單個(gè)股票盈利2)

采集交流 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 146 次瀏覽 ? 2022-04-18 07:10 ? 來(lái)自相關(guān)話(huà)題

  文章采集調用(中國的股票市場(chǎng)上盈利,每周都有單個(gè)股票盈利2)
  目標:在中國股市盈利,單只股票每周盈利2%,月總盈利超過(guò)2%
  計劃實(shí)現:Pycharm + Anaconda3 + Python3 + Django + AKShare + MongoDB
  當前實(shí)現:Pycharm + Anaconda3 + Python3 + Flask + AKShare
  未來(lái)可能會(huì )用到:MongoDB、SQLAlchemy、baostock、Tushare
  機器學(xué)習將在未來(lái)的實(shí)踐中逐步使用。
  實(shí)現方法
  上一篇文章寫(xiě)過(guò)采集的方法。本文文章收錄完整代碼和調用代碼。
  使用后臺執行的方法。
  gupiao.py如下:
  
import akshare as ak
import threading
import datetime
import os
from threading import Thread
def get_start():
start_stock_daily()
# 這里就是核心了,調用這部分就會(huì )自動(dòng)下載 深圳A(yíng)股 的所有股票的歷史記錄
def start_stock_daily(indicator="A股列表", folder="sz_a", prefix="sz"):
file_path = "D:/work/data/" + folder + "/"
file_path_name = get_sz_a(file_path, indicator)
print(file_path_name)
num = 0
with open(file_path_name, "r", encoding=&#39;UTF-8&#39;) as stock_lines:
for stock_line in stock_lines.readlines():
num = num + 1
if num == 1:
continue
stock_line_arr = stock_line.split("|")
symbol = prefix + stock_line_arr[5]
print("股票信息=" + symbol + "||" + stock_line_arr[6])
stock_csv = get_stock_daily(file_path, symbol)
print("stock_csv=" + stock_csv)
# 獲得深圳主板A股列表,每天獲取一次不重復獲取
# file_path 需要全路徑,以 | 進(jìn)行間隔
# indicator 可選參數 "A股列表", "B股列表", "AB股列表", "上市公司列表", "主板", "中小企業(yè)板", "創(chuàng )業(yè)板"
def get_sz_a(file_path, indicator="A股列表"):
today = datetime.datetime.today()
file_name = "sz_a_" + today.strftime(&#39;%Y%m%d&#39;) + ".csv"
if not os.path.exists(file_path): # 如果路徑不存在則創(chuàng )建
os.makedirs(file_path)
if os.path.exists(file_path + file_name):
print("今日已經(jīng)獲取無(wú)需再次獲取," + today.strftime(&#39;%Y%m%d&#39;))
return file_path + file_name
stock_info_sz_df = ak.stock_info_sz_name_code(indicator=indicator)
stock_info_sz_df.to_csv(file_path + file_name, sep="|")
print(&#39;獲取深圳主板A股列表并存儲為CSV!&#39; + today.strftime(&#39;%Y%m%d&#39;))
return file_path + file_name
# 根據股票代碼獲取股票歷史數據
# symbol 股票代碼 需要前綴 sh 上海 sz 深圳,例如:sz300846
def get_stock_daily(file_path, symbol):
stock_zh_a_daily_hfq_df = ak.stock_zh_a_daily(symbol=symbol) # 返回不復權的數據
file_name = symbol + &#39;.csv&#39;
stock_zh_a_daily_hfq_df.to_csv(file_path + file_name)
return file_path + file_name
  調用下載的部分,注意我隨便寫(xiě)的名字,請根據情況修改,app.py如下:
  from flask import Flask
import akshare as ak
import gupiao
import datetime
import os
from concurrent.futures import ThreadPoolExecutor
import time
executor = ThreadPoolExecutor(2)
app = Flask(__name__)
@app.route(&#39;/test_thread&#39;)
def test_thread():
executor.submit(gupiao.get_start)
return "thread is running at background !!!"
if __name__ == &#39;__main__&#39;:
app.run()
  使用Flask框架,生成一個(gè)項目,然后在app.py中創(chuàng )建一個(gè)gupiao.py,并運行該項目。
  在瀏覽器中訪(fǎng)問(wèn):5000/test_thread
  可以在后臺看到圖片,整個(gè)深圳A(yíng)股的下載時(shí)間大約是2小時(shí)到3小時(shí)。
  
  歷史股票數據
  如圖下載到本地
  
  歷史股票數據
  爬取數據部分完成,接下來(lái)就是過(guò)濾了。 查看全部

  文章采集調用(中國的股票市場(chǎng)上盈利,每周都有單個(gè)股票盈利2)
  目標:在中國股市盈利,單只股票每周盈利2%,月總盈利超過(guò)2%
  計劃實(shí)現:Pycharm + Anaconda3 + Python3 + Django + AKShare + MongoDB
  當前實(shí)現:Pycharm + Anaconda3 + Python3 + Flask + AKShare
  未來(lái)可能會(huì )用到:MongoDB、SQLAlchemy、baostock、Tushare
  機器學(xué)習將在未來(lái)的實(shí)踐中逐步使用。
  實(shí)現方法
  上一篇文章寫(xiě)過(guò)采集的方法。本文文章收錄完整代碼和調用代碼。
  使用后臺執行的方法。
  gupiao.py如下:
  
import akshare as ak
import threading
import datetime
import os
from threading import Thread
def get_start():
start_stock_daily()
# 這里就是核心了,調用這部分就會(huì )自動(dòng)下載 深圳A(yíng)股 的所有股票的歷史記錄
def start_stock_daily(indicator="A股列表", folder="sz_a", prefix="sz"):
file_path = "D:/work/data/" + folder + "/"
file_path_name = get_sz_a(file_path, indicator)
print(file_path_name)
num = 0
with open(file_path_name, "r", encoding=&#39;UTF-8&#39;) as stock_lines:
for stock_line in stock_lines.readlines():
num = num + 1
if num == 1:
continue
stock_line_arr = stock_line.split("|")
symbol = prefix + stock_line_arr[5]
print("股票信息=" + symbol + "||" + stock_line_arr[6])
stock_csv = get_stock_daily(file_path, symbol)
print("stock_csv=" + stock_csv)
# 獲得深圳主板A股列表,每天獲取一次不重復獲取
# file_path 需要全路徑,以 | 進(jìn)行間隔
# indicator 可選參數 "A股列表", "B股列表", "AB股列表", "上市公司列表", "主板", "中小企業(yè)板", "創(chuàng )業(yè)板"
def get_sz_a(file_path, indicator="A股列表"):
today = datetime.datetime.today()
file_name = "sz_a_" + today.strftime(&#39;%Y%m%d&#39;) + ".csv"
if not os.path.exists(file_path): # 如果路徑不存在則創(chuàng )建
os.makedirs(file_path)
if os.path.exists(file_path + file_name):
print("今日已經(jīng)獲取無(wú)需再次獲取," + today.strftime(&#39;%Y%m%d&#39;))
return file_path + file_name
stock_info_sz_df = ak.stock_info_sz_name_code(indicator=indicator)
stock_info_sz_df.to_csv(file_path + file_name, sep="|")
print(&#39;獲取深圳主板A股列表并存儲為CSV!&#39; + today.strftime(&#39;%Y%m%d&#39;))
return file_path + file_name
# 根據股票代碼獲取股票歷史數據
# symbol 股票代碼 需要前綴 sh 上海 sz 深圳,例如:sz300846
def get_stock_daily(file_path, symbol):
stock_zh_a_daily_hfq_df = ak.stock_zh_a_daily(symbol=symbol) # 返回不復權的數據
file_name = symbol + &#39;.csv&#39;
stock_zh_a_daily_hfq_df.to_csv(file_path + file_name)
return file_path + file_name
  調用下載的部分,注意我隨便寫(xiě)的名字,請根據情況修改,app.py如下:
  from flask import Flask
import akshare as ak
import gupiao
import datetime
import os
from concurrent.futures import ThreadPoolExecutor
import time
executor = ThreadPoolExecutor(2)
app = Flask(__name__)
@app.route(&#39;/test_thread&#39;)
def test_thread():
executor.submit(gupiao.get_start)
return "thread is running at background !!!"
if __name__ == &#39;__main__&#39;:
app.run()
  使用Flask框架,生成一個(gè)項目,然后在app.py中創(chuàng )建一個(gè)gupiao.py,并運行該項目。
  在瀏覽器中訪(fǎng)問(wèn):5000/test_thread
  可以在后臺看到圖片,整個(gè)深圳A(yíng)股的下載時(shí)間大約是2小時(shí)到3小時(shí)。
  
  歷史股票數據
  如圖下載到本地
  
  歷史股票數據
  爬取數據部分完成,接下來(lái)就是過(guò)濾了。

文章采集調用(如何使用采集功能去采集一個(gè)圖片類(lèi)的網(wǎng)站(組圖))

采集交流 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 188 次瀏覽 ? 2022-04-17 17:12 ? 來(lái)自相關(guān)話(huà)題

  文章采集調用(如何使用采集功能去采集一個(gè)圖片類(lèi)的網(wǎng)站(組圖))
  前言:本文章主要介紹如何使用采集函數來(lái)采集一個(gè)圖片類(lèi)網(wǎng)站。本次選擇的目標站點(diǎn)為:戰酷網(wǎng)名作鑒賞欄目,網(wǎng)址為:. 本文將介紹如何處理收錄 采集 分頁(yè)的頁(yè)面以及如何使用簡(jiǎn)單的過(guò)濾規則。本文分為三部分:第一部分主要介紹如何進(jìn)入采集界面以及添加新采集節點(diǎn)的第一步:設置基本信息和URL索引頁(yè)面規則;第二部分,主要是引入新的采集節點(diǎn)的第二步:設置字段獲取規則;第三節主要介紹采集如何指定節點(diǎn)以及如何導出采集內容。
  進(jìn)入下面的第一部分。
  1.1進(jìn)入采集節點(diǎn)管理界面
  如圖1),在后臺管理界面主菜單點(diǎn)擊“采集”,再點(diǎn)擊“采集節點(diǎn)管理”進(jìn)入采集節點(diǎn)管理界面,如圖(圖2).
  
  圖 1 - 后臺管理界面
  
  圖2-采集節點(diǎn)管理界面
  1.2. 添加新節點(diǎn)
  在采集節點(diǎn)管理界面,點(diǎn)擊左下角“添加新節點(diǎn)”或右上角“添加新節點(diǎn)”(如圖2),可以輸入“選擇內容模型”界面,如(如圖3),
  
  圖 3 - 選擇內容模型界面
  在“選擇內容模型”界面的下拉列表框中,有“普通文章”和“圖片采集”可供選擇。
  根據頁(yè)面類(lèi)型為采集,選擇對應的內容模型。本文選擇“圖片采集”,點(diǎn)擊確定,即可進(jìn)入“添加采集節點(diǎn):第一步設置基本信息和URL索引頁(yè)面規則”界面,如圖(圖4)@ &gt; ,
  
  圖4 - 添加采集節點(diǎn):第一步設置基本信息和URL索引頁(yè)面規則
  1.2.1 設置節點(diǎn)基本信息
  
  圖 5 - 節點(diǎn)基本信息
  如圖(圖5),這里只是獲取“目標頁(yè)面代碼”的方法,其他設置請參考前面的文章。具體操作步驟:
  (a) 打開(kāi) 采集: 所針對的目標頁(yè)面;
  (b) 右擊選擇“查看源文件”找到“charset”,如圖(圖6),
  
  圖 6 - 查看源文件
  等號后面的代碼就是需要填寫(xiě)的“編碼格式”,這里是“utf-8”。
  填寫(xiě)后,如圖(圖7),
  
  圖 7 - 設置后節點(diǎn)的基本信息
  檢查后,進(jìn)入下一步。
  1.2.2 設置列表URL獲取規則
  
  圖 8 - 列出 URL 獲取規則
  如(圖8),這里是設置采集的文章列表頁(yè)的匹配規則。具體步驟:
  (a) 首先,回到打開(kāi)的列表頁(yè)面,找到瀏覽器的URL地址欄中顯示的URL和頁(yè)面的分頁(yè)符部分。如(圖9)和(圖10))所示,
  
  圖 9 - 瀏覽器的 URL 地址欄
  
  圖 10 - 頁(yè)面提要
  (b) 點(diǎn)擊“2”打開(kāi)文章列表頁(yè)面的第二頁(yè),再次找到瀏覽器的URL地址欄顯示的URL和頁(yè)面的換頁(yè)部分,如圖(圖12)和(如圖13),
  
  圖 11 - 第二頁(yè)的 URL
  
  圖 12 - 第二頁(yè)上的換頁(yè)
  (c) 在打開(kāi)的列表頁(yè)第二頁(yè),點(diǎn)擊(1)返回列表頁(yè)第一頁(yè),頁(yè)面換頁(yè)部分同上圖10,只是瀏覽器URL地址欄顯示的URL與上圖9不同,如圖(圖13),
  
  圖 13 - 第一個(gè)頁(yè)面的 URL
  (d) 由(b)和(c)可知,這里采集的列表頁(yè)的URL遵循如下規則:
  !0!0!200!(*)!1!0!0/. 為了安全起見(jiàn),請為自己測試更多列表頁(yè)面。規則確定后,在“匹配網(wǎng)址”中,填寫(xiě)列表頁(yè)后面的規則。
  (e) 最后,根據需要指定采集的頁(yè)碼或常規數,并設置其遞增規則。
  至此,“List URL獲取規則”部分就設置好了。最終結果,如圖(圖14)@>,
  
  圖 14 - 設置后的 URL 獲取規則列表
  確認無(wú)誤后,進(jìn)行下一步。
  1.2.3設置文章網(wǎng)址匹配規則
  
  圖 15 - 文章 URL 匹配規則
  下面是設置采集列表頁(yè)的匹配規則。
  具體步驟:
  
(a)對于“區域開(kāi)始的HTML”,可以在已打開(kāi)的列表首頁(yè),單擊右鍵后選擇“查看源文件”查找出第一篇文章的標題“高清壁紙”來(lái)獲得,如(圖16)所示,
  
  圖 16 - 查看源文件中第一個(gè) 文章 的標題
  通過(guò)觀(guān)察不難看出,“”是整個(gè)列表的結尾,后面的“”是頁(yè)面的分頁(yè)符。所以,在“HTML 結尾區域”中,應該用“”填充,意思是到第一個(gè)結尾。
  (c) 觀(guān)察圖16和圖17中文章的標題部分,可以發(fā)現標題的鏈接地址收錄“=.html”。因此,在“必須收錄”中,填寫(xiě)“=.html”。
  至此,“文章URL匹配規則”就設置好了。填寫(xiě)后,如圖(圖18),
  
  圖 18 - 文章 設置后的 URL 匹配規則
  通過(guò)以上三個(gè)小節,已經(jīng)設置了添加采集節點(diǎn)的第一步。設置后的最終結果,如圖(圖19),
  
  圖19 - 設置后新增采集節點(diǎn):第一步設置基本信息和URL索引頁(yè)面規則
  全部完成并勾選后,點(diǎn)擊“保存信息并進(jìn)入下一步”。如果前面設置正確,點(diǎn)擊后會(huì )進(jìn)入“添加采集節點(diǎn):測試URL索引頁(yè)面規則設置的基本信息和URL獲取規則測試”頁(yè)面,看到對應的文章列表地址. 如圖(圖20),
  
  圖 20 - URL 獲取規則測試
  確認無(wú)誤后,點(diǎn)擊“保存信息并進(jìn)入下一步”。否則,單擊“返回上一步進(jìn)行更改”。
  到這里,第一節就結束了。進(jìn)入下面的第二部分。. . 查看全部

  文章采集調用(如何使用采集功能去采集一個(gè)圖片類(lèi)的網(wǎng)站(組圖))
  前言:本文章主要介紹如何使用采集函數來(lái)采集一個(gè)圖片類(lèi)網(wǎng)站。本次選擇的目標站點(diǎn)為:戰酷網(wǎng)名作鑒賞欄目,網(wǎng)址為:. 本文將介紹如何處理收錄 采集 分頁(yè)的頁(yè)面以及如何使用簡(jiǎn)單的過(guò)濾規則。本文分為三部分:第一部分主要介紹如何進(jìn)入采集界面以及添加新采集節點(diǎn)的第一步:設置基本信息和URL索引頁(yè)面規則;第二部分,主要是引入新的采集節點(diǎn)的第二步:設置字段獲取規則;第三節主要介紹采集如何指定節點(diǎn)以及如何導出采集內容。
  進(jìn)入下面的第一部分。
  1.1進(jìn)入采集節點(diǎn)管理界面
  如圖1),在后臺管理界面主菜單點(diǎn)擊“采集”,再點(diǎn)擊“采集節點(diǎn)管理”進(jìn)入采集節點(diǎn)管理界面,如圖(圖2).
  
  圖 1 - 后臺管理界面
  
  圖2-采集節點(diǎn)管理界面
  1.2. 添加新節點(diǎn)
  在采集節點(diǎn)管理界面,點(diǎn)擊左下角“添加新節點(diǎn)”或右上角“添加新節點(diǎn)”(如圖2),可以輸入“選擇內容模型”界面,如(如圖3),
  
  圖 3 - 選擇內容模型界面
  在“選擇內容模型”界面的下拉列表框中,有“普通文章”和“圖片采集”可供選擇。
  根據頁(yè)面類(lèi)型為采集,選擇對應的內容模型。本文選擇“圖片采集”,點(diǎn)擊確定,即可進(jìn)入“添加采集節點(diǎn):第一步設置基本信息和URL索引頁(yè)面規則”界面,如圖(圖4)@ &gt; ,
  
  圖4 - 添加采集節點(diǎn):第一步設置基本信息和URL索引頁(yè)面規則
  1.2.1 設置節點(diǎn)基本信息
  
  圖 5 - 節點(diǎn)基本信息
  如圖(圖5),這里只是獲取“目標頁(yè)面代碼”的方法,其他設置請參考前面的文章。具體操作步驟:
  (a) 打開(kāi) 采集: 所針對的目標頁(yè)面;
  (b) 右擊選擇“查看源文件”找到“charset”,如圖(圖6),
  
  圖 6 - 查看源文件
  等號后面的代碼就是需要填寫(xiě)的“編碼格式”,這里是“utf-8”。
  填寫(xiě)后,如圖(圖7),
  
  圖 7 - 設置后節點(diǎn)的基本信息
  檢查后,進(jìn)入下一步。
  1.2.2 設置列表URL獲取規則
  
  圖 8 - 列出 URL 獲取規則
  如(圖8),這里是設置采集的文章列表頁(yè)的匹配規則。具體步驟:
  (a) 首先,回到打開(kāi)的列表頁(yè)面,找到瀏覽器的URL地址欄中顯示的URL和頁(yè)面的分頁(yè)符部分。如(圖9)和(圖10))所示,
  
  圖 9 - 瀏覽器的 URL 地址欄
  
  圖 10 - 頁(yè)面提要
  (b) 點(diǎn)擊“2”打開(kāi)文章列表頁(yè)面的第二頁(yè),再次找到瀏覽器的URL地址欄顯示的URL和頁(yè)面的換頁(yè)部分,如圖(圖12)和(如圖13),
  
  圖 11 - 第二頁(yè)的 URL
  
  圖 12 - 第二頁(yè)上的換頁(yè)
  (c) 在打開(kāi)的列表頁(yè)第二頁(yè),點(diǎn)擊(1)返回列表頁(yè)第一頁(yè),頁(yè)面換頁(yè)部分同上圖10,只是瀏覽器URL地址欄顯示的URL與上圖9不同,如圖(圖13),
  
  圖 13 - 第一個(gè)頁(yè)面的 URL
  (d) 由(b)和(c)可知,這里采集的列表頁(yè)的URL遵循如下規則:
  !0!0!200!(*)!1!0!0/. 為了安全起見(jiàn),請為自己測試更多列表頁(yè)面。規則確定后,在“匹配網(wǎng)址”中,填寫(xiě)列表頁(yè)后面的規則。
  (e) 最后,根據需要指定采集的頁(yè)碼或常規數,并設置其遞增規則。
  至此,“List URL獲取規則”部分就設置好了。最終結果,如圖(圖14)@>,
  
  圖 14 - 設置后的 URL 獲取規則列表
  確認無(wú)誤后,進(jìn)行下一步。
  1.2.3設置文章網(wǎng)址匹配規則
  
  圖 15 - 文章 URL 匹配規則
  下面是設置采集列表頁(yè)的匹配規則。
  具體步驟:
  
(a)對于“區域開(kāi)始的HTML”,可以在已打開(kāi)的列表首頁(yè),單擊右鍵后選擇“查看源文件”查找出第一篇文章的標題“高清壁紙”來(lái)獲得,如(圖16)所示,
  
  圖 16 - 查看源文件中第一個(gè) 文章 的標題
  通過(guò)觀(guān)察不難看出,“”是整個(gè)列表的結尾,后面的“”是頁(yè)面的分頁(yè)符。所以,在“HTML 結尾區域”中,應該用“”填充,意思是到第一個(gè)結尾。
  (c) 觀(guān)察圖16和圖17中文章的標題部分,可以發(fā)現標題的鏈接地址收錄“=.html”。因此,在“必須收錄”中,填寫(xiě)“=.html”。
  至此,“文章URL匹配規則”就設置好了。填寫(xiě)后,如圖(圖18),
  
  圖 18 - 文章 設置后的 URL 匹配規則
  通過(guò)以上三個(gè)小節,已經(jīng)設置了添加采集節點(diǎn)的第一步。設置后的最終結果,如圖(圖19),
  
  圖19 - 設置后新增采集節點(diǎn):第一步設置基本信息和URL索引頁(yè)面規則
  全部完成并勾選后,點(diǎn)擊“保存信息并進(jìn)入下一步”。如果前面設置正確,點(diǎn)擊后會(huì )進(jìn)入“添加采集節點(diǎn):測試URL索引頁(yè)面規則設置的基本信息和URL獲取規則測試”頁(yè)面,看到對應的文章列表地址. 如圖(圖20),
  
  圖 20 - URL 獲取規則測試
  確認無(wú)誤后,點(diǎn)擊“保存信息并進(jìn)入下一步”。否則,單擊“返回上一步進(jìn)行更改”。
  到這里,第一節就結束了。進(jìn)入下面的第二部分。. .

文章采集調用(跑到圖文加工店,說(shuō)給點(diǎn)素材,中年老板:騷年你來(lái)對了)

采集交流 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 141 次瀏覽 ? 2022-04-15 08:38 ? 來(lái)自相關(guān)話(huà)題

  文章采集調用(跑到圖文加工店,說(shuō)給點(diǎn)素材,中年老板:騷年你來(lái)對了)
  我去了圖形加工店,要了一些材料。中年老板:騷年,你說(shuō)得對,我們這里有很多存貨。我們擁有您需要的一切,無(wú)論是否為 JPG、PSD、AI、AE、AV……
  我去了菜市場(chǎng),給我舉了一些例子。水果賣(mài)家:朋友知道貨。今天剛到的李子很清爽。缺點(diǎn)是太甜了!隔壁賣(mài)糖炒栗子的小伙伸了伸脖子:大哥,帶個(gè)剛出鍋的袋子!
  嗯……定義很重要,所以我們今天說(shuō)的就是閱讀中獲得的文本內容,寫(xiě)作、演講、推理等參考和引用的材料和例子。
  其實(shí)很多大牛都寫(xiě)過(guò)管理自己的知識庫,整理自己的知識體系文章等文章,素材和例子只是其中很小的一部分。和那些大牛相比,這次我只關(guān)注材料和例子。這個(gè)入口點(diǎn)非常小。如果你已經(jīng)建立了自己完整的知識框架和結構,非常歡迎你給我意見(jiàn)和批評,面帶微笑。
  一、素材和例子有什么用1.征服觀(guān)眾
  在寫(xiě)作或演講時(shí),通常圍繞一個(gè)主題,你所要做的就是讓讀者或聽(tīng)眾理解并接受你所說(shuō)的話(huà)。如果你像教科書(shū)一樣一個(gè)一個(gè)地遵守規則,你可能會(huì )失去很多觀(guān)眾。這種情況在演講時(shí)尤其明顯。當你偶爾低頭在臺上尋求所謂的眼神交流和互動(dòng)感,發(fā)現臺下很多人都只是笑瞇瞇地盯著(zhù)桌子看,你應該明白你說(shuō)的沒(méi)那么有趣他們作為微博或朋友圈。
  適當的書(shū)面或口語(yǔ)引用可以幫助最大程度地防止這種情況發(fā)生。在寫(xiě)作中引用例子可以幫助讀者避免長(cháng)時(shí)間閱讀的疲勞,同時(shí)加深對內容的理解;演講中生動(dòng)的例子更有意義,使你表達的內容更容易被聽(tīng)眾接受和理解。此外,成人注意力的時(shí)間曲線(xiàn)有其特定的規律。舉兩個(gè)生動(dòng)的例子,在聽(tīng)眾精力下降、容易分心的時(shí)候,可以瞬間重新集中注意力,保證演講的良好效果。
  2.已關(guān)注
  你身邊應該有幾個(gè)這樣的朋友。飯桌上,談山,如切瓜切菜。上至天文地理玄學(xué)玄學(xué),三體四書(shū)五道口,下至官民悲喜肉離奇故事,五花八門(mén)。境界中,入流而不入流的,如果被TA接管了,也別想帶回去。如果你也想成為黨的中心(當然,最好排除個(gè)人自我宣傳的內容),一個(gè)反駁大片的引用,那么素材和例子的采集可以讓你玩得更輕松. 李笑來(lái)老師在《花時(shí)間做朋友》中提到,父親在公共場(chǎng)合總是能言善辯。一時(shí)間,他原以為父親是個(gè)記憶力極好的人,后來(lái)才發(fā)現,父親的秘密,其實(shí)是一本寫(xiě)滿(mǎn)記錄的筆記本。所謂口才,就是根據采集到的資料和例子,什么時(shí)候可以應用到什么場(chǎng)合。
  3.生理原因(個(gè)人原因)
  英語(yǔ)中有一句話(huà):在我的舌尖上,字面意思是“在我的舌尖上”。它實(shí)際上意味著(zhù)這些話(huà)在嘴唇上,但我突然想不起來(lái)了。在專(zhuān)注于采集資料和例子之前,我有很多類(lèi)似的經(jīng)歷。我清楚地記得,前一天,甚至幾個(gè)小時(shí)前,我碰巧看到了一個(gè)可以支持我觀(guān)點(diǎn)的例子,但我不記得細節和來(lái)源了。孤歌獨娘,沒(méi)有結果。這時(shí)候,我會(huì )感到后背和喉嚨有刺的不適感,相當難受。我認為這種感覺(jué)來(lái)自于沒(méi)有保存適當的材料或示例的遺憾。
  因此,采集和整理資料和例子已經(jīng)成為我的日常習慣之一?!皶?shū)籍只有在使用時(shí)才會(huì )被使用?!?古人早就發(fā)出過(guò)類(lèi)似的感嘆。事實(shí)上,對于掌握了很多新工具和新方法的現代人來(lái)說(shuō),采集和整理資料和實(shí)例其實(shí)并沒(méi)有想象中的那么麻煩。
  二、如何采集資料和例子1.采集資料和例子
  由于我說(shuō)的采集整理主要是針對文字內容,所以采集資料和例子的主要來(lái)源如下:
  (1)書(shū)籍
  如今,知識產(chǎn)權的保護普遍受到重視。很多書(shū)的內容不能直接在網(wǎng)上獲取,只能在閱讀后摘錄和總結。
  - 電子書(shū)
  目前國內外新書(shū)趨勢是電子版和紙質(zhì)版同步推出。電子版通常比較便宜,可以直接在亞馬遜等官網(wǎng)購買(mǎi)。尤其是剛出版的新書(shū),基本上只能找到付費版(各種號稱(chēng)免費的網(wǎng)站往往最后都指向付費版網(wǎng)址)。對于已經(jīng)上架一段時(shí)間的書(shū)籍,會(huì )有各種免費的電子版流出,其中大部分是PDF,但質(zhì)量參差不齊。還有一件事,我找電子書(shū)的建議是,如果5-10分鐘內沒(méi)有找到合適的版本,基本可以放棄。不值得花更多寶貴的時(shí)間在無(wú)法保證的免費和優(yōu)質(zhì)內容上,并直接購買(mǎi)電子書(shū)。版本性?xún)r(jià)比更高,付費也體現了對知識的尊重。
  以目前主流的亞馬遜官網(wǎng)為例,購買(mǎi)完成后會(huì )自動(dòng)推送到KINDLE。為了方便后續的整理和檢索,我會(huì )使用CALIBER軟件和DEDRM插件將亞馬遜下載的AZW3格式轉換成EPUB格式,然后把書(shū)放進(jìn)書(shū)里。所需內容采集在印象筆記中(僅供學(xué)習參考,絕不參與D版盈利),讓大量摘抄和引用的內容輕松復制到印象筆記保存和同步,不易丟失和容易搜索。
  - 紙質(zhì)書(shū)
  有的書(shū)比較經(jīng)典但年代久遠,多次再版都沒(méi)有電子版;還有非小說(shuō)類(lèi)的書(shū),因為我個(gè)人喜歡邊看書(shū)邊寫(xiě)讀書(shū)筆記,所以買(mǎi)了紙質(zhì)版。對于這種紙質(zhì)書(shū),做長(cháng)篇摘錄很不方便,手工摘錄也相當耗時(shí)。幸運的是,我在某寶上找到了一款手持掃描筆,可以快速將紙張內容掃描成可編輯的文本格式,比手動(dòng)輸入效率高出很多倍。以前看過(guò)萬(wàn)維剛的《沒(méi)想到》。其中有許多科學(xué)證據的例子。段落很長(cháng)。錢(qián)是不能存的。對于紙質(zhì)書(shū)閱讀量大、喜歡做閱讀筆記的朋友來(lái)說(shuō),掃描筆是個(gè)值得推薦的工具。
  (2)微信內容
  微信是大多數人使用頻率最高的手機應用,用得上不用說(shuō)。我關(guān)聯(lián)了印象筆記和有道云筆記這兩個(gè)官方微信賬號。我一般把值得采集的內容隨時(shí)保存在云端,然后在電腦上整理總結。
  (3)網(wǎng)頁(yè)內容
  當我瀏覽網(wǎng)頁(yè)時(shí),我也會(huì )保存我發(fā)現的好內容。復制粘貼部分太麻煩了。為此,我使用了印象筆記的網(wǎng)頁(yè)剪輯插件??梢赃x擇整頁(yè),網(wǎng)頁(yè)正文,或者去廣告等等,形式多樣,非常體貼。
  (4)其他
  其他來(lái)源不是我采集整理資料的主流渠道,比如微信聊天記錄等,我靠谷歌度娘的一些技巧整理成文字保存。
  2.材料和例子的組織
  采集后一定要整理好,否則起不到任何價(jià)值。整理的目的是為了更好的使用,單靠大腦很難把采集到的所有內容都記住。作為一個(gè)85后,我經(jīng)常聽(tīng)到90后說(shuō):“哎呀!怎么記不住了?年紀大了,腦子就不行了?!?更習慣了)。事實(shí)上,人的大腦就像一臺電腦。存儲容量有一定的上限。此外,人腦也有遺忘機制。對于長(cháng)時(shí)間不使用的內容,大腦會(huì )選擇忘記釋放存儲空間讓經(jīng)常使用的模塊運行。因此,我們需要將采集到的資料和實(shí)例進(jìn)行更有效的整理,以方便后續的高效調用,減輕大腦的負擔,
  以印象筆記為例。完成采集動(dòng)作后,你的印象筆記現在應該有相當多的內容了,但是它們是雜亂無(wú)章的。這時(shí)候,你需要做三件事:
  第一步是取名字。這是最直接的內容分類(lèi)方法,也是最原創(chuàng )的信息搜索渠道。我通常給內容命名的方式是:日期+類(lèi)型+一般內容摘要,例如:20161011知乎LIVE-詹老師——一種不需要意志力的習慣養成方法,這樣不管我怎么想“獵鷹”、“習慣”、“知乎”或日期,可以找到這個(gè)材料。
  第二步是分類(lèi)。采集到的內容按照類(lèi)型設置成文件夾并進(jìn)行相應分類(lèi),就像在電腦上為各種文檔創(chuàng )建文件夾一樣。我現在常用的文件夾有:個(gè)人(存放個(gè)人內容和其他私密內容,可選擇加密)、日常工作(與工作相關(guān)的資料或內容)、學(xué)習(與學(xué)習、寫(xiě)作、成長(cháng)等相關(guān))等。此設置的優(yōu)點(diǎn)是,當您不記得要搜索的具體內容,但可以確定需要查找的一般類(lèi)別時(shí),您可以過(guò)濾掉其他大類(lèi)并縮小搜索范圍。但是,當內容積累到一定程度時(shí),這樣的分類(lèi)范圍還是太粗,不夠細。此時(shí),
  第三步也是最重要的一步是添加標簽!標簽!標簽?。ㄖ匾氖虑檎f(shuō)三遍)按文件夾分類(lèi)的材料有一個(gè)巨大的缺陷。一份資料或例子只能歸入一個(gè)文件夾。如果要放到第二個(gè)文件夾,只能復制粘貼一次。. 數據本質(zhì)上是復雜的。復制粘貼會(huì )導致多個(gè)重復的搜索結果,并且會(huì )白白占用寶貴的云存儲空間。強烈不推薦。因此,此時(shí)需要對素材或示例做的是添加標簽,而不是添加一個(gè)標簽,而是添加盡可能多的標簽,并根據該素材所能窮盡的所有相關(guān)特性進(jìn)行標記. 例如:之前在簡(jiǎn)書(shū)上看到一篇文章文章《經(jīng)驗:我如何找到電子書(shū)》,它教你如何搜索你需要的電子書(shū)或電子版資料。我把這個(gè)文章按類(lèi)別放在study文件夾里,但其實(shí)我在工作中也用到了電子資料的搜索技巧。所以我給這個(gè)文章加了“e-book”、“search”、“resource”、“skill”等幾個(gè)標簽,方便以后寫(xiě)文章來(lái)明確調用資源,找電子書(shū),在普及工作技能等角度的時(shí)候可以找到這個(gè)文章。
  標記有兩個(gè)非常大的好處。首先,打標簽可以幫助你思考反芻:除了解釋原創(chuàng )內容之外,這個(gè)材料或例子還能用于哪些其他方面?它還可以用來(lái)支持哪些其他論點(diǎn)?這與上面提到的相同。李笑來(lái)老師和他的父親,通過(guò)記錄和思考,在什么時(shí)間、什么地點(diǎn)、什么情況下記下了筆記本上的內容。是“思維拓展”的簡(jiǎn)化版,也可以體現來(lái)這里幫助你進(jìn)一步理解內容。二是通過(guò)打標簽會(huì )有很多意想不到的“驚喜”。我之前寫(xiě)過(guò)《學(xué)會(huì )花錢(qián)》這本書(shū)的書(shū)評。當我分析涉及概率論的章節時(shí),我點(diǎn)擊了我標記為“
  三、調用的方法
  所謂調用就是搜索所有你認為你能想到的關(guān)鍵詞來(lái)找到你想要的內容,其中一些在上一篇文章中已經(jīng)提到過(guò)??梢源_定,文件名的搜索是最直接的。如果沒(méi)有,可以在大類(lèi)中搜索,縮小范圍,或者使用標簽疊加的方法進(jìn)行多維搜索。目前我最常用的方法是確定大類(lèi),然后使用多個(gè)標簽疊加搜索的方法,這種方法是最具方向性的。如果您想在搜索時(shí)獲得靈感,僅使用一個(gè)關(guān)鍵字瀏覽或單擊一組單獨的標簽通常會(huì )給您帶來(lái)意想不到的東西。
  李敖拆書(shū)的著(zhù)名例子就是材料采集和轉移的最好例子。以下文字來(lái)自對他的采訪(fǎng):
  我很少忘記讀過(guò)的書(shū),李敖,為什么?方法很好。有什么辦法?無(wú)情。所有的剪刀和美工刀都用了,當這本書(shū)被肢解時(shí),它被切開(kāi)。這個(gè)頁(yè)面我需要,這個(gè)段落我需要,我按類(lèi)別分開(kāi)。背面呢?復印一份,或者一開(kāi)始買(mǎi)兩本書(shū),剪開(kāi)整理一下,想看的部分留著(zhù)。結果一本書(shū)寫(xiě)完了,書(shū)也被肢解了。我就是這樣看書(shū)的。
  分類(lèi)是如何劃分的?我有很多自己制作的剪輯,我在剪輯上寫(xiě)下并分類(lèi)所有信息。讀完一本書(shū),全都進(jìn)了我的文件夾。我可以分出上千個(gè)班級,分得很細。例如,按照圖書(shū)館的分類(lèi),有哲學(xué)類(lèi)和宗教類(lèi);宗教類(lèi)別進(jìn)一步分為佛教、道教和天主教。我,李敖,可以分為更多的細節。天主教徒可以細分,神父是一類(lèi)。牧師也可以細分。同性戀神父是一類(lèi),世俗神父是另一類(lèi)。女同性戀是一類(lèi),修女是世俗的,是另一類(lèi)。
  書(shū)中的任何相關(guān)內容都會(huì )進(jìn)入我的個(gè)人資料。輸入什么?當我想寫(xiě)小說(shuō)時(shí),我需要這些信息,打開(kāi)信息,然后就寫(xiě)出來(lái)?;蛘甙l(fā)生了什么事,這與修女是同性戀有關(guān)。我想表達我對新聞的想法,帶來(lái)新聞,打開(kāi)我的數據,合并兩者,文章馬上就寫(xiě)出來(lái)。
  也就是說(shuō),看完這本書(shū),我被五匹馬撕成了八塊。但我被迷住了。我不記得這些材料。我小心翼翼地把它們掛起來(lái),放在文件夾里。我的記憶只需要記住這些標題。標題是根據我的習慣劃分的?;旧隙际欠g成英文單詞,排列成英文字母,偶爾也有一些中文。"
  四、備注
  在明確了材料采集的方法和好處之后,有兩點(diǎn)需要注意:
  1.確認是真的。
  邏輯中有一個(gè)重要的概念:“合乎邏輯就是符合真理”。如果采集的材料和例子來(lái)自歪曲事實(shí)或報道,那么即使它符合你的觀(guān)點(diǎn),支持你的說(shuō)法,也沒(méi)有任何意義,甚至會(huì )產(chǎn)生相反的效果,讓讀者或聽(tīng)眾覺(jué)得你是一個(gè)無(wú)法區分的人。對真假撒謊的人,從而大大降低了你觀(guān)點(diǎn)的可信度。此外,即使材料是真實(shí)的,也很可能是時(shí)間敏感的。因此,在使用素材或示例時(shí),一定要記得檢查內容是否真實(shí),是否仍然準確,并及時(shí)更新篩選。如果涉及收錄日期或數據的新聞、歷史、人文等,
  2.通知消息來(lái)源。
  引用示例時(shí),在不引用來(lái)源的情況下表達內容會(huì )讓人感到缺乏信任。如果讀者或聽(tīng)眾對您引用的材料或示例特別感興趣,他們可能希望通過(guò)這些資源了解更詳細的內容。因此,在引用資料或例子時(shí),盡量告知出處,同時(shí)不影響表達的流暢性。
  五、總結
  查看有關(guān)采集和組織示例的所需要點(diǎn):
  ——為什么要注意資料和例子的采集
  1.征服全場(chǎng)
  2.已關(guān)注
  3.(個(gè)人原因)
  - 采集和組織方法
  1.采集來(lái)源
  (1)書(shū)籍 - 電子版、紙質(zhì)版
  (2)微信
  (3) 網(wǎng)頁(yè)
  (4)其他
  - 調用方法
  文件名、類(lèi)別、標簽覆蓋
  - 防范措施
  1.確認真相
  2.通知來(lái)源
  話(huà)雖如此,我只是想把我采集整理的習慣分享給大家,讓分享好的東西更有意義。無(wú)論是寫(xiě)作、口語(yǔ)、推理,還是豐富對話(huà)、獲取知識,還是成為一個(gè)有趣的人,好的材料和例子都是非常有幫助的?!昂糜浶圆蝗鐗墓P”,在這個(gè)時(shí)代應該改為“好記性不如壞手指”。雖然一開(kāi)始可能看起來(lái)有些麻煩,但當你意識到經(jīng)常采集和整理的好處時(shí),你絕對不會(huì )停下來(lái)。想到通過(guò)采集整理,就可以控制這么大的素材庫供自己使用,是多么有趣啊。
  你為什么不也試試呢? 查看全部

  文章采集調用(跑到圖文加工店,說(shuō)給點(diǎn)素材,中年老板:騷年你來(lái)對了)
  我去了圖形加工店,要了一些材料。中年老板:騷年,你說(shuō)得對,我們這里有很多存貨。我們擁有您需要的一切,無(wú)論是否為 JPG、PSD、AI、AE、AV……
  我去了菜市場(chǎng),給我舉了一些例子。水果賣(mài)家:朋友知道貨。今天剛到的李子很清爽。缺點(diǎn)是太甜了!隔壁賣(mài)糖炒栗子的小伙伸了伸脖子:大哥,帶個(gè)剛出鍋的袋子!
  嗯……定義很重要,所以我們今天說(shuō)的就是閱讀中獲得的文本內容,寫(xiě)作、演講、推理等參考和引用的材料和例子。
  其實(shí)很多大牛都寫(xiě)過(guò)管理自己的知識庫,整理自己的知識體系文章等文章,素材和例子只是其中很小的一部分。和那些大牛相比,這次我只關(guān)注材料和例子。這個(gè)入口點(diǎn)非常小。如果你已經(jīng)建立了自己完整的知識框架和結構,非常歡迎你給我意見(jiàn)和批評,面帶微笑。
  一、素材和例子有什么用1.征服觀(guān)眾
  在寫(xiě)作或演講時(shí),通常圍繞一個(gè)主題,你所要做的就是讓讀者或聽(tīng)眾理解并接受你所說(shuō)的話(huà)。如果你像教科書(shū)一樣一個(gè)一個(gè)地遵守規則,你可能會(huì )失去很多觀(guān)眾。這種情況在演講時(shí)尤其明顯。當你偶爾低頭在臺上尋求所謂的眼神交流和互動(dòng)感,發(fā)現臺下很多人都只是笑瞇瞇地盯著(zhù)桌子看,你應該明白你說(shuō)的沒(méi)那么有趣他們作為微博或朋友圈。
  適當的書(shū)面或口語(yǔ)引用可以幫助最大程度地防止這種情況發(fā)生。在寫(xiě)作中引用例子可以幫助讀者避免長(cháng)時(shí)間閱讀的疲勞,同時(shí)加深對內容的理解;演講中生動(dòng)的例子更有意義,使你表達的內容更容易被聽(tīng)眾接受和理解。此外,成人注意力的時(shí)間曲線(xiàn)有其特定的規律。舉兩個(gè)生動(dòng)的例子,在聽(tīng)眾精力下降、容易分心的時(shí)候,可以瞬間重新集中注意力,保證演講的良好效果。
  2.已關(guān)注
  你身邊應該有幾個(gè)這樣的朋友。飯桌上,談山,如切瓜切菜。上至天文地理玄學(xué)玄學(xué),三體四書(shū)五道口,下至官民悲喜肉離奇故事,五花八門(mén)。境界中,入流而不入流的,如果被TA接管了,也別想帶回去。如果你也想成為黨的中心(當然,最好排除個(gè)人自我宣傳的內容),一個(gè)反駁大片的引用,那么素材和例子的采集可以讓你玩得更輕松. 李笑來(lái)老師在《花時(shí)間做朋友》中提到,父親在公共場(chǎng)合總是能言善辯。一時(shí)間,他原以為父親是個(gè)記憶力極好的人,后來(lái)才發(fā)現,父親的秘密,其實(shí)是一本寫(xiě)滿(mǎn)記錄的筆記本。所謂口才,就是根據采集到的資料和例子,什么時(shí)候可以應用到什么場(chǎng)合。
  3.生理原因(個(gè)人原因)
  英語(yǔ)中有一句話(huà):在我的舌尖上,字面意思是“在我的舌尖上”。它實(shí)際上意味著(zhù)這些話(huà)在嘴唇上,但我突然想不起來(lái)了。在專(zhuān)注于采集資料和例子之前,我有很多類(lèi)似的經(jīng)歷。我清楚地記得,前一天,甚至幾個(gè)小時(shí)前,我碰巧看到了一個(gè)可以支持我觀(guān)點(diǎn)的例子,但我不記得細節和來(lái)源了。孤歌獨娘,沒(méi)有結果。這時(shí)候,我會(huì )感到后背和喉嚨有刺的不適感,相當難受。我認為這種感覺(jué)來(lái)自于沒(méi)有保存適當的材料或示例的遺憾。
  因此,采集和整理資料和例子已經(jīng)成為我的日常習慣之一?!皶?shū)籍只有在使用時(shí)才會(huì )被使用?!?古人早就發(fā)出過(guò)類(lèi)似的感嘆。事實(shí)上,對于掌握了很多新工具和新方法的現代人來(lái)說(shuō),采集和整理資料和實(shí)例其實(shí)并沒(méi)有想象中的那么麻煩。
  二、如何采集資料和例子1.采集資料和例子
  由于我說(shuō)的采集整理主要是針對文字內容,所以采集資料和例子的主要來(lái)源如下:
  (1)書(shū)籍
  如今,知識產(chǎn)權的保護普遍受到重視。很多書(shū)的內容不能直接在網(wǎng)上獲取,只能在閱讀后摘錄和總結。
  - 電子書(shū)
  目前國內外新書(shū)趨勢是電子版和紙質(zhì)版同步推出。電子版通常比較便宜,可以直接在亞馬遜等官網(wǎng)購買(mǎi)。尤其是剛出版的新書(shū),基本上只能找到付費版(各種號稱(chēng)免費的網(wǎng)站往往最后都指向付費版網(wǎng)址)。對于已經(jīng)上架一段時(shí)間的書(shū)籍,會(huì )有各種免費的電子版流出,其中大部分是PDF,但質(zhì)量參差不齊。還有一件事,我找電子書(shū)的建議是,如果5-10分鐘內沒(méi)有找到合適的版本,基本可以放棄。不值得花更多寶貴的時(shí)間在無(wú)法保證的免費和優(yōu)質(zhì)內容上,并直接購買(mǎi)電子書(shū)。版本性?xún)r(jià)比更高,付費也體現了對知識的尊重。
  以目前主流的亞馬遜官網(wǎng)為例,購買(mǎi)完成后會(huì )自動(dòng)推送到KINDLE。為了方便后續的整理和檢索,我會(huì )使用CALIBER軟件和DEDRM插件將亞馬遜下載的AZW3格式轉換成EPUB格式,然后把書(shū)放進(jìn)書(shū)里。所需內容采集在印象筆記中(僅供學(xué)習參考,絕不參與D版盈利),讓大量摘抄和引用的內容輕松復制到印象筆記保存和同步,不易丟失和容易搜索。
  - 紙質(zhì)書(shū)
  有的書(shū)比較經(jīng)典但年代久遠,多次再版都沒(méi)有電子版;還有非小說(shuō)類(lèi)的書(shū),因為我個(gè)人喜歡邊看書(shū)邊寫(xiě)讀書(shū)筆記,所以買(mǎi)了紙質(zhì)版。對于這種紙質(zhì)書(shū),做長(cháng)篇摘錄很不方便,手工摘錄也相當耗時(shí)。幸運的是,我在某寶上找到了一款手持掃描筆,可以快速將紙張內容掃描成可編輯的文本格式,比手動(dòng)輸入效率高出很多倍。以前看過(guò)萬(wàn)維剛的《沒(méi)想到》。其中有許多科學(xué)證據的例子。段落很長(cháng)。錢(qián)是不能存的。對于紙質(zhì)書(shū)閱讀量大、喜歡做閱讀筆記的朋友來(lái)說(shuō),掃描筆是個(gè)值得推薦的工具。
  (2)微信內容
  微信是大多數人使用頻率最高的手機應用,用得上不用說(shuō)。我關(guān)聯(lián)了印象筆記和有道云筆記這兩個(gè)官方微信賬號。我一般把值得采集的內容隨時(shí)保存在云端,然后在電腦上整理總結。
  (3)網(wǎng)頁(yè)內容
  當我瀏覽網(wǎng)頁(yè)時(shí),我也會(huì )保存我發(fā)現的好內容。復制粘貼部分太麻煩了。為此,我使用了印象筆記的網(wǎng)頁(yè)剪輯插件??梢赃x擇整頁(yè),網(wǎng)頁(yè)正文,或者去廣告等等,形式多樣,非常體貼。
  (4)其他
  其他來(lái)源不是我采集整理資料的主流渠道,比如微信聊天記錄等,我靠谷歌度娘的一些技巧整理成文字保存。
  2.材料和例子的組織
  采集后一定要整理好,否則起不到任何價(jià)值。整理的目的是為了更好的使用,單靠大腦很難把采集到的所有內容都記住。作為一個(gè)85后,我經(jīng)常聽(tīng)到90后說(shuō):“哎呀!怎么記不住了?年紀大了,腦子就不行了?!?更習慣了)。事實(shí)上,人的大腦就像一臺電腦。存儲容量有一定的上限。此外,人腦也有遺忘機制。對于長(cháng)時(shí)間不使用的內容,大腦會(huì )選擇忘記釋放存儲空間讓經(jīng)常使用的模塊運行。因此,我們需要將采集到的資料和實(shí)例進(jìn)行更有效的整理,以方便后續的高效調用,減輕大腦的負擔,
  以印象筆記為例。完成采集動(dòng)作后,你的印象筆記現在應該有相當多的內容了,但是它們是雜亂無(wú)章的。這時(shí)候,你需要做三件事:
  第一步是取名字。這是最直接的內容分類(lèi)方法,也是最原創(chuàng )的信息搜索渠道。我通常給內容命名的方式是:日期+類(lèi)型+一般內容摘要,例如:20161011知乎LIVE-詹老師——一種不需要意志力的習慣養成方法,這樣不管我怎么想“獵鷹”、“習慣”、“知乎”或日期,可以找到這個(gè)材料。
  第二步是分類(lèi)。采集到的內容按照類(lèi)型設置成文件夾并進(jìn)行相應分類(lèi),就像在電腦上為各種文檔創(chuàng )建文件夾一樣。我現在常用的文件夾有:個(gè)人(存放個(gè)人內容和其他私密內容,可選擇加密)、日常工作(與工作相關(guān)的資料或內容)、學(xué)習(與學(xué)習、寫(xiě)作、成長(cháng)等相關(guān))等。此設置的優(yōu)點(diǎn)是,當您不記得要搜索的具體內容,但可以確定需要查找的一般類(lèi)別時(shí),您可以過(guò)濾掉其他大類(lèi)并縮小搜索范圍。但是,當內容積累到一定程度時(shí),這樣的分類(lèi)范圍還是太粗,不夠細。此時(shí),
  第三步也是最重要的一步是添加標簽!標簽!標簽?。ㄖ匾氖虑檎f(shuō)三遍)按文件夾分類(lèi)的材料有一個(gè)巨大的缺陷。一份資料或例子只能歸入一個(gè)文件夾。如果要放到第二個(gè)文件夾,只能復制粘貼一次。. 數據本質(zhì)上是復雜的。復制粘貼會(huì )導致多個(gè)重復的搜索結果,并且會(huì )白白占用寶貴的云存儲空間。強烈不推薦。因此,此時(shí)需要對素材或示例做的是添加標簽,而不是添加一個(gè)標簽,而是添加盡可能多的標簽,并根據該素材所能窮盡的所有相關(guān)特性進(jìn)行標記. 例如:之前在簡(jiǎn)書(shū)上看到一篇文章文章《經(jīng)驗:我如何找到電子書(shū)》,它教你如何搜索你需要的電子書(shū)或電子版資料。我把這個(gè)文章按類(lèi)別放在study文件夾里,但其實(shí)我在工作中也用到了電子資料的搜索技巧。所以我給這個(gè)文章加了“e-book”、“search”、“resource”、“skill”等幾個(gè)標簽,方便以后寫(xiě)文章來(lái)明確調用資源,找電子書(shū),在普及工作技能等角度的時(shí)候可以找到這個(gè)文章。
  標記有兩個(gè)非常大的好處。首先,打標簽可以幫助你思考反芻:除了解釋原創(chuàng )內容之外,這個(gè)材料或例子還能用于哪些其他方面?它還可以用來(lái)支持哪些其他論點(diǎn)?這與上面提到的相同。李笑來(lái)老師和他的父親,通過(guò)記錄和思考,在什么時(shí)間、什么地點(diǎn)、什么情況下記下了筆記本上的內容。是“思維拓展”的簡(jiǎn)化版,也可以體現來(lái)這里幫助你進(jìn)一步理解內容。二是通過(guò)打標簽會(huì )有很多意想不到的“驚喜”。我之前寫(xiě)過(guò)《學(xué)會(huì )花錢(qián)》這本書(shū)的書(shū)評。當我分析涉及概率論的章節時(shí),我點(diǎn)擊了我標記為“
  三、調用的方法
  所謂調用就是搜索所有你認為你能想到的關(guān)鍵詞來(lái)找到你想要的內容,其中一些在上一篇文章中已經(jīng)提到過(guò)??梢源_定,文件名的搜索是最直接的。如果沒(méi)有,可以在大類(lèi)中搜索,縮小范圍,或者使用標簽疊加的方法進(jìn)行多維搜索。目前我最常用的方法是確定大類(lèi),然后使用多個(gè)標簽疊加搜索的方法,這種方法是最具方向性的。如果您想在搜索時(shí)獲得靈感,僅使用一個(gè)關(guān)鍵字瀏覽或單擊一組單獨的標簽通常會(huì )給您帶來(lái)意想不到的東西。
  李敖拆書(shū)的著(zhù)名例子就是材料采集和轉移的最好例子。以下文字來(lái)自對他的采訪(fǎng):
  我很少忘記讀過(guò)的書(shū),李敖,為什么?方法很好。有什么辦法?無(wú)情。所有的剪刀和美工刀都用了,當這本書(shū)被肢解時(shí),它被切開(kāi)。這個(gè)頁(yè)面我需要,這個(gè)段落我需要,我按類(lèi)別分開(kāi)。背面呢?復印一份,或者一開(kāi)始買(mǎi)兩本書(shū),剪開(kāi)整理一下,想看的部分留著(zhù)。結果一本書(shū)寫(xiě)完了,書(shū)也被肢解了。我就是這樣看書(shū)的。
  分類(lèi)是如何劃分的?我有很多自己制作的剪輯,我在剪輯上寫(xiě)下并分類(lèi)所有信息。讀完一本書(shū),全都進(jìn)了我的文件夾。我可以分出上千個(gè)班級,分得很細。例如,按照圖書(shū)館的分類(lèi),有哲學(xué)類(lèi)和宗教類(lèi);宗教類(lèi)別進(jìn)一步分為佛教、道教和天主教。我,李敖,可以分為更多的細節。天主教徒可以細分,神父是一類(lèi)。牧師也可以細分。同性戀神父是一類(lèi),世俗神父是另一類(lèi)。女同性戀是一類(lèi),修女是世俗的,是另一類(lèi)。
  書(shū)中的任何相關(guān)內容都會(huì )進(jìn)入我的個(gè)人資料。輸入什么?當我想寫(xiě)小說(shuō)時(shí),我需要這些信息,打開(kāi)信息,然后就寫(xiě)出來(lái)?;蛘甙l(fā)生了什么事,這與修女是同性戀有關(guān)。我想表達我對新聞的想法,帶來(lái)新聞,打開(kāi)我的數據,合并兩者,文章馬上就寫(xiě)出來(lái)。
  也就是說(shuō),看完這本書(shū),我被五匹馬撕成了八塊。但我被迷住了。我不記得這些材料。我小心翼翼地把它們掛起來(lái),放在文件夾里。我的記憶只需要記住這些標題。標題是根據我的習慣劃分的?;旧隙际欠g成英文單詞,排列成英文字母,偶爾也有一些中文。"
  四、備注
  在明確了材料采集的方法和好處之后,有兩點(diǎn)需要注意:
  1.確認是真的。
  邏輯中有一個(gè)重要的概念:“合乎邏輯就是符合真理”。如果采集的材料和例子來(lái)自歪曲事實(shí)或報道,那么即使它符合你的觀(guān)點(diǎn),支持你的說(shuō)法,也沒(méi)有任何意義,甚至會(huì )產(chǎn)生相反的效果,讓讀者或聽(tīng)眾覺(jué)得你是一個(gè)無(wú)法區分的人。對真假撒謊的人,從而大大降低了你觀(guān)點(diǎn)的可信度。此外,即使材料是真實(shí)的,也很可能是時(shí)間敏感的。因此,在使用素材或示例時(shí),一定要記得檢查內容是否真實(shí),是否仍然準確,并及時(shí)更新篩選。如果涉及收錄日期或數據的新聞、歷史、人文等,
  2.通知消息來(lái)源。
  引用示例時(shí),在不引用來(lái)源的情況下表達內容會(huì )讓人感到缺乏信任。如果讀者或聽(tīng)眾對您引用的材料或示例特別感興趣,他們可能希望通過(guò)這些資源了解更詳細的內容。因此,在引用資料或例子時(shí),盡量告知出處,同時(shí)不影響表達的流暢性。
  五、總結
  查看有關(guān)采集和組織示例的所需要點(diǎn):
  ——為什么要注意資料和例子的采集
  1.征服全場(chǎng)
  2.已關(guān)注
  3.(個(gè)人原因)
  - 采集和組織方法
  1.采集來(lái)源
  (1)書(shū)籍 - 電子版、紙質(zhì)版
  (2)微信
  (3) 網(wǎng)頁(yè)
  (4)其他
  - 調用方法
  文件名、類(lèi)別、標簽覆蓋
  - 防范措施
  1.確認真相
  2.通知來(lái)源
  話(huà)雖如此,我只是想把我采集整理的習慣分享給大家,讓分享好的東西更有意義。無(wú)論是寫(xiě)作、口語(yǔ)、推理,還是豐富對話(huà)、獲取知識,還是成為一個(gè)有趣的人,好的材料和例子都是非常有幫助的?!昂糜浶圆蝗鐗墓P”,在這個(gè)時(shí)代應該改為“好記性不如壞手指”。雖然一開(kāi)始可能看起來(lái)有些麻煩,但當你意識到經(jīng)常采集和整理的好處時(shí),你絕對不會(huì )停下來(lái)。想到通過(guò)采集整理,就可以控制這么大的素材庫供自己使用,是多么有趣啊。
  你為什么不也試試呢?

文章采集調用(注意事項雷電模擬器要用3.96.0版本的,用7.1版本我的思路)

采集交流 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 141 次瀏覽 ? 2022-04-14 20:26 ? 來(lái)自相關(guān)話(huà)題

  文章采集調用(注意事項雷電模擬器要用3.96.0版本的,用7.1版本我的思路)
  一、算法
  算法確實(shí)好用,但是破解的難度大家應該都知道。隨著(zhù)版本的更新,算法會(huì )經(jīng)常發(fā)生變化,你的軟件也會(huì )隨著(zhù)變化而更新,這樣會(huì )增加開(kāi)發(fā)成本。,你不得不說(shuō)采集效率!就個(gè)人而言,我不認為它快得多。畢竟,訪(fǎng)問(wèn)的頻率也是有限的。訪(fǎng)問(wèn)后不能更改代理,對嗎?這個(gè)多少錢(qián)?
  二、瀏覽器
  不知道大家有沒(méi)有發(fā)現,用戶(hù)的主頁(yè)是用瀏覽器打開(kāi)的,但是用戶(hù)的作品卻完全沒(méi)有顯示出來(lái)。相信很多人的算法都是通過(guò)網(wǎng)頁(yè)版獲取的,所以這就造成了一個(gè)現象,網(wǎng)頁(yè)版的算法,往往需要多次請求才能返回一組數據。當然,不排除有通過(guò)APP逆向獲得的大神。這種情況我就不在這里討論了,因為我也是半桶水倒過(guò)來(lái)。
  三、捕獲(提琴手)
  Fiddler 可以說(shuō)是 TCP 之外非常常見(jiàn)的抓包工具。證書(shū)安裝好后,什么都不用做。缺點(diǎn)是沒(méi)有API可以調用,除非你重新開(kāi)發(fā)。一個(gè)調用第三方的dll庫,我們在自己的程序中調用這個(gè)dll,把自己當做代理服務(wù)器,所有經(jīng)過(guò)的請求都會(huì )先經(jīng)過(guò)我這邊,這樣我就可以處理數據了。
  四、備注
  迅雷模擬器使用3.96.0版本,apk使用7.1版本
  我的思路:
  1.使用Fiddler做代理服務(wù)器,具體代碼和dll庫可以百度。
  
  2.用模擬器操作,安裝證書(shū),掛代理,你刷你的視頻,我的服務(wù)器會(huì )自動(dòng)過(guò)濾數據,留下有用的
  (1)配置模擬器,模擬器選擇手機版本,分辨率可選
  
  (2)使用模擬器中的瀏覽器打開(kāi)軟件上的鏈接(地址:端口),例如(192.168.0.109:8888)@ &gt; 繼續安裝證書(shū)
  
  (3)配置模擬器網(wǎng)絡(luò )代理
  
  就這么簡(jiǎn)單,不知道你看懂Get了嗎?這個(gè)方法,不管你放在什么app上,都是可行的,只要你要抓的數據是通過(guò)http或者https傳輸的,那么這個(gè)方法是可以的,但是在模擬器段,你可能要寫(xiě)一個(gè)腳本操作請求的觸發(fā)器。與破解算法相比,自動(dòng)化腳本可不是小菜一碟。
  關(guān)于抖音在模擬器中無(wú)法正常顯示數據,可以下載7.1版本的apk,不屏蔽模擬器的7.1版本。
  這是我自己的批量去水印下載的示例。有興趣的可以自行下載試用。有問(wèn)題或者需要更多功能可以私信我交流。下載后右鍵屬性解鎖,否則可能無(wú)法正常使用。
  對了,win7系統可能不行,因為很多win7 Fiddler證書(shū)無(wú)法正常安裝,所以軟件不能抓取https,這個(gè)可以自己測試。 查看全部

  文章采集調用(注意事項雷電模擬器要用3.96.0版本的,用7.1版本我的思路)
  一、算法
  算法確實(shí)好用,但是破解的難度大家應該都知道。隨著(zhù)版本的更新,算法會(huì )經(jīng)常發(fā)生變化,你的軟件也會(huì )隨著(zhù)變化而更新,這樣會(huì )增加開(kāi)發(fā)成本。,你不得不說(shuō)采集效率!就個(gè)人而言,我不認為它快得多。畢竟,訪(fǎng)問(wèn)的頻率也是有限的。訪(fǎng)問(wèn)后不能更改代理,對嗎?這個(gè)多少錢(qián)?
  二、瀏覽器
  不知道大家有沒(méi)有發(fā)現,用戶(hù)的主頁(yè)是用瀏覽器打開(kāi)的,但是用戶(hù)的作品卻完全沒(méi)有顯示出來(lái)。相信很多人的算法都是通過(guò)網(wǎng)頁(yè)版獲取的,所以這就造成了一個(gè)現象,網(wǎng)頁(yè)版的算法,往往需要多次請求才能返回一組數據。當然,不排除有通過(guò)APP逆向獲得的大神。這種情況我就不在這里討論了,因為我也是半桶水倒過(guò)來(lái)。
  三、捕獲(提琴手)
  Fiddler 可以說(shuō)是 TCP 之外非常常見(jiàn)的抓包工具。證書(shū)安裝好后,什么都不用做。缺點(diǎn)是沒(méi)有API可以調用,除非你重新開(kāi)發(fā)。一個(gè)調用第三方的dll庫,我們在自己的程序中調用這個(gè)dll,把自己當做代理服務(wù)器,所有經(jīng)過(guò)的請求都會(huì )先經(jīng)過(guò)我這邊,這樣我就可以處理數據了。
  四、備注
  迅雷模擬器使用3.96.0版本,apk使用7.1版本
  我的思路:
  1.使用Fiddler做代理服務(wù)器,具體代碼和dll庫可以百度。
  
  2.用模擬器操作,安裝證書(shū),掛代理,你刷你的視頻,我的服務(wù)器會(huì )自動(dòng)過(guò)濾數據,留下有用的
  (1)配置模擬器,模擬器選擇手機版本,分辨率可選
  
  (2)使用模擬器中的瀏覽器打開(kāi)軟件上的鏈接(地址:端口),例如(192.168.0.109:8888)@ &gt; 繼續安裝證書(shū)
  
  (3)配置模擬器網(wǎng)絡(luò )代理
  
  就這么簡(jiǎn)單,不知道你看懂Get了嗎?這個(gè)方法,不管你放在什么app上,都是可行的,只要你要抓的數據是通過(guò)http或者https傳輸的,那么這個(gè)方法是可以的,但是在模擬器段,你可能要寫(xiě)一個(gè)腳本操作請求的觸發(fā)器。與破解算法相比,自動(dòng)化腳本可不是小菜一碟。
  關(guān)于抖音在模擬器中無(wú)法正常顯示數據,可以下載7.1版本的apk,不屏蔽模擬器的7.1版本。
  這是我自己的批量去水印下載的示例。有興趣的可以自行下載試用。有問(wèn)題或者需要更多功能可以私信我交流。下載后右鍵屬性解鎖,否則可能無(wú)法正常使用。
  對了,win7系統可能不行,因為很多win7 Fiddler證書(shū)無(wú)法正常安裝,所以軟件不能抓取https,這個(gè)可以自己測試。

文章采集調用(2.采集支持調用奶盤(pán)API接口(組圖)采集數據 )

采集交流 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 155 次瀏覽 ? 2022-04-14 17:06 ? 來(lái)自相關(guān)話(huà)題

  文章采集調用(2.采集支持調用奶盤(pán)API接口(組圖)采集數據
)
  優(yōu)采云采集支持調用奶盤(pán)API接口,處理采集的數據標題和內容等;
  溫馨提示:第三方API接入功能需要用戶(hù)提供第三方接口賬號信息(即用戶(hù)需要注冊第三方接口,調用第三方接口產(chǎn)生的一切費用自理)由用戶(hù));
  詳細使用步驟
  1. 創(chuàng )建奶盤(pán)API接口配置一、API配置入口:
  點(diǎn)擊控制臺左側列表中的【第三方服務(wù)配置】==點(diǎn)擊【第三方內容API接入】==點(diǎn)擊【第三方API配置管理】==最后點(diǎn)擊【奶鍋】 Open API] 創(chuàng )建接口配置;
  
  二、配置API接口信息:
  【Purchased Authorized User】和【Purchased Authorization Code】是從后臺獲取API授權信息,填寫(xiě)優(yōu)采云;
  【API版】是奶鍋網(wǎng)購買(mǎi)對應的套餐:百度優(yōu)化版、AI智能版;
  
  
  注意:由于牛奶托盤(pán)每次調用限制為最多65000個(gè)字符(包括html代碼),當內容長(cháng)度超過(guò)時(shí),優(yōu)采云會(huì )被分割多次調用。這個(gè)操作會(huì )增加api調用次數,開(kāi)銷(xiāo)也會(huì )相應增加。這是用戶(hù)需要承擔的成本。使用前一定要注意?。?!
  2. 創(chuàng )建 API 處理規則
  API處理規則,可以通過(guò)調用API接口設置處理哪些字段的內容;
  一、API處理規則入口:
  點(diǎn)擊控制臺左側列表中的【第三方服務(wù)配置】==,點(diǎn)擊【第三方內容API接入】==進(jìn)入【API處理規則管理】頁(yè)面,最后點(diǎn)擊【+添加API處理規則]創(chuàng )建API處理規則;
  
  二、API處理規則配置:
  
  3. API 處理規則使用
  API處理規則有兩種使用方式:手動(dòng)執行和自動(dòng)執行:
  一、手動(dòng)執行API處理規則:
  在采集任務(wù)的【結果數據&amp;發(fā)布】選項卡中,點(diǎn)擊【SEO&amp;API&amp;翻譯等工具】按鈕==選擇【第三方API執行】欄==選擇對應的API處理規則= ="執行(數據范圍有兩種執行方式,根據發(fā)布狀態(tài)批量執行和根據列表中選擇的數據執行);
  
  二、自動(dòng)執行API處理規則:
  
  啟用 API 處理的自動(dòng)執行。任務(wù)完成后采集會(huì )自動(dòng)執行API處理。一般配合定時(shí)采集和自動(dòng)發(fā)布功能使用非常方便;
  在任務(wù)的【自動(dòng)化:發(fā)布&amp;SEO&amp;翻譯】選項卡【自動(dòng)執行第三方API配置】==勾選【采集,自動(dòng)執行API】選項==選擇要執行的API處理規則= ="選擇API接口處理的數據范圍(一般選擇'待釋放',all會(huì )導致所有數據重復執行),最后點(diǎn)擊保存;
  4. API處理結果并發(fā)布一、查看API接口處理結果:
  API接口處理后的內容會(huì )保存為一個(gè)新的字段,如:標題處理后的新字段:`title_milk tray`,內容處理后的新字段:`content_milk tray`,在【結果數據&amp;發(fā)布】和可以查看數據預覽界面。
  提示:執行 API 處理規則需要一段時(shí)間。執行完成后,頁(yè)面會(huì )自動(dòng)刷新,并出現API接口處理的新字段;
  
  二、API接口處理后的內容發(fā)布
  發(fā)布文章前,修改發(fā)布目標第二步的映射字段,重新選擇標題和內容到API接口處理后添加的對應字段`title_milk tray'和`content_milk tray';
  
  提示:如果發(fā)布目標中無(wú)法選擇新字段,請在任務(wù)下復制或新建發(fā)布目標,然后在新發(fā)布目標中選擇新字段即可。詳細教程請參考發(fā)布目標中不能選擇的字段。
  5. 奶盤(pán)-API接口常見(jiàn)問(wèn)題及解決方法一、API處理規則和SEO規則如何結合使用?
  系統默認對title和content字段進(jìn)行SEO功能,需要修改為SEO規則中的`title_milk tray'和`content_milk tray'字段;
   查看全部

  文章采集調用(2.采集支持調用奶盤(pán)API接口(組圖)采集數據
)
  優(yōu)采云采集支持調用奶盤(pán)API接口,處理采集的數據標題和內容等;
  溫馨提示:第三方API接入功能需要用戶(hù)提供第三方接口賬號信息(即用戶(hù)需要注冊第三方接口,調用第三方接口產(chǎn)生的一切費用自理)由用戶(hù));
  詳細使用步驟
  1. 創(chuàng )建奶盤(pán)API接口配置一、API配置入口:
  點(diǎn)擊控制臺左側列表中的【第三方服務(wù)配置】==點(diǎn)擊【第三方內容API接入】==點(diǎn)擊【第三方API配置管理】==最后點(diǎn)擊【奶鍋】 Open API] 創(chuàng )建接口配置;
  
  二、配置API接口信息:
  【Purchased Authorized User】和【Purchased Authorization Code】是從后臺獲取API授權信息,填寫(xiě)優(yōu)采云;
  【API版】是奶鍋網(wǎng)購買(mǎi)對應的套餐:百度優(yōu)化版、AI智能版;
  
  
  注意:由于牛奶托盤(pán)每次調用限制為最多65000個(gè)字符(包括html代碼),當內容長(cháng)度超過(guò)時(shí),優(yōu)采云會(huì )被分割多次調用。這個(gè)操作會(huì )增加api調用次數,開(kāi)銷(xiāo)也會(huì )相應增加。這是用戶(hù)需要承擔的成本。使用前一定要注意?。?!
  2. 創(chuàng )建 API 處理規則
  API處理規則,可以通過(guò)調用API接口設置處理哪些字段的內容;
  一、API處理規則入口:
  點(diǎn)擊控制臺左側列表中的【第三方服務(wù)配置】==,點(diǎn)擊【第三方內容API接入】==進(jìn)入【API處理規則管理】頁(yè)面,最后點(diǎn)擊【+添加API處理規則]創(chuàng )建API處理規則;
  
  二、API處理規則配置:
  
  3. API 處理規則使用
  API處理規則有兩種使用方式:手動(dòng)執行和自動(dòng)執行:
  一、手動(dòng)執行API處理規則:
  在采集任務(wù)的【結果數據&amp;發(fā)布】選項卡中,點(diǎn)擊【SEO&amp;API&amp;翻譯等工具】按鈕==選擇【第三方API執行】欄==選擇對應的API處理規則= ="執行(數據范圍有兩種執行方式,根據發(fā)布狀態(tài)批量執行和根據列表中選擇的數據執行);
  
  二、自動(dòng)執行API處理規則:
  
  啟用 API 處理的自動(dòng)執行。任務(wù)完成后采集會(huì )自動(dòng)執行API處理。一般配合定時(shí)采集和自動(dòng)發(fā)布功能使用非常方便;
  在任務(wù)的【自動(dòng)化:發(fā)布&amp;SEO&amp;翻譯】選項卡【自動(dòng)執行第三方API配置】==勾選【采集,自動(dòng)執行API】選項==選擇要執行的API處理規則= ="選擇API接口處理的數據范圍(一般選擇'待釋放',all會(huì )導致所有數據重復執行),最后點(diǎn)擊保存;
  4. API處理結果并發(fā)布一、查看API接口處理結果:
  API接口處理后的內容會(huì )保存為一個(gè)新的字段,如:標題處理后的新字段:`title_milk tray`,內容處理后的新字段:`content_milk tray`,在【結果數據&amp;發(fā)布】和可以查看數據預覽界面。
  提示:執行 API 處理規則需要一段時(shí)間。執行完成后,頁(yè)面會(huì )自動(dòng)刷新,并出現API接口處理的新字段;
  
  二、API接口處理后的內容發(fā)布
  發(fā)布文章前,修改發(fā)布目標第二步的映射字段,重新選擇標題和內容到API接口處理后添加的對應字段`title_milk tray'和`content_milk tray';
  
  提示:如果發(fā)布目標中無(wú)法選擇新字段,請在任務(wù)下復制或新建發(fā)布目標,然后在新發(fā)布目標中選擇新字段即可。詳細教程請參考發(fā)布目標中不能選擇的字段。
  5. 奶盤(pán)-API接口常見(jiàn)問(wèn)題及解決方法一、API處理規則和SEO規則如何結合使用?
  系統默認對title和content字段進(jìn)行SEO功能,需要修改為SEO規則中的`title_milk tray'和`content_milk tray'字段;
  

文章采集調用( 開(kāi)發(fā)環(huán)境JDK1.8.0javassist本章本章GA本章涉及源碼的開(kāi)發(fā))

采集交流 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 129 次瀏覽 ? 2022-04-13 14:15 ? 來(lái)自相關(guān)話(huà)題

  文章采集調用(
開(kāi)發(fā)環(huán)境JDK1.8.0javassist本章本章GA本章涉及源碼的開(kāi)發(fā))
  
  一、前言
  字節碼編程插樁技術(shù)常結合Javaagent技術(shù)用于系統的非侵入式監控,可以替代方法中的硬編碼操作。例如,您需要監控一個(gè)方法,包括;方法信息、執行時(shí)間、輸入輸出參數、執行鏈接、異常。那么就非常適合用這樣的技術(shù)手段進(jìn)行加工。
  為了體現這部分的核心內容,本文將只使用Javassist技術(shù)對一段方法字節碼進(jìn)行instrument,最后輸出該方法的執行信息,如下;
  Method - 后續字節碼增強操作的測試方法
  public Integer strToInt(String str01, String str02) {
return Integer.parseInt(str01);
}
  監控 - 方法的字節碼增強后,輸出監控信息
  監控 - Begin
方法:org.itstack.demo.javassist.ApiTest.strToInt
入參:["str01","str02"] 入參[類(lèi)型]:["java.lang.String","java.lang.String"] 入數[值]:["1","2"]
出參:java.lang.Integer 出參[值]:1
耗時(shí):59(s)
監控 - End
  有了這樣的監控方案,我們基本上可以輸出方法執行過(guò)程中的所有信息。然后通過(guò)后期的改進(jìn),將監控信息顯示在界面上,并實(shí)時(shí)發(fā)出警報。不僅提高了系統的監控質(zhì)量,也便于研發(fā)排查和定位問(wèn)題。
  這很好!然后我們一步步開(kāi)始使用javassist進(jìn)行字節碼插樁,就達到了我們的監控效果。
  二、開(kāi)發(fā)環(huán)境JDK 1.8.0javassist 3.12.1.GA本章涉及的源碼為:itstack-demo-bytecode -1-04,可以關(guān)注公眾號:bugstack 蟲(chóng)洞棧,回復源碼下載即可。您將獲得下載鏈接列表。打開(kāi)后第十七期“因為我有很多開(kāi)源代碼”,記得給個(gè)Star!三、技術(shù)實(shí)現1. 獲取方法的基本信息1.1 獲取類(lèi)
  ClassPool pool = ClassPool.getDefault();
// 獲取類(lèi)
CtClass ctClass = pool.get(org.itstack.demo.javassist.ApiTest.class.getName());
ctClass.replaceClassName("ApiTest", "ApiTest02");
String clazzName = ctClass.getName();
  通過(guò)類(lèi)名獲取類(lèi)信息,這里可以替換類(lèi)名。它還包括一些其他操作來(lái)獲取類(lèi)中的屬性,例如;ctClass.getSimpleName()、ctClass.getAnnotations() 等等。
  1.2 如何獲得
  CtMethod ctMethod = ctClass.getDeclaredMethod("strToInt");
String methodName = ctMethod.getName();
  通過(guò)getDeclaredMethod獲取方法的CtMethod的內容。之后,您可以獲取方法名稱(chēng)等信息。
  1.3 方法信息
  MethodInfo methodInfo = ctMethod.getMethodInfo();
  MethodInfo 收錄方法信息;名稱(chēng)、類(lèi)型等
  1.4 種方法類(lèi)型
  boolean isStatic = (methodInfo.getAccessFlags() & AccessFlag.STATIC) != 0;
  通過(guò)methodInfo.getAccessFlags()獲取方法的標識符,然后使用AND運算AccessFlag.STATIC判斷該方法是否為靜態(tài)方法。因為靜態(tài)方法會(huì )影響后續參數名的獲取,所以靜態(tài)方法的第一個(gè)參數就是this,需要排除。
  1.5 方法:輸入參數信息{name and type}
  CodeAttribute codeAttribute = methodInfo.getCodeAttribute();
LocalVariableAttribute attr = (LocalVariableAttribute) codeAttribute.getAttribute(LocalVariableAttribute.tag);
CtClass[] parameterTypes = ctMethod.getParameterTypes();
  1.6 方法;參數信息
  CtClass returnType = ctMethod.getReturnType();
String returnTypeName = returnType.getName();
  對于方法的參數信息,只需要獲取參數類(lèi)型即可。
  1.7 輸出所有獲取的信息
  System.out.println("類(lèi)名:" + clazzName);
System.out.println("方法:" + methodName);
System.out.println("類(lèi)型:" + (isStatic ? "靜態(tài)方法" : "非靜態(tài)方法"));
System.out.println("描述:" + methodInfo.getDescriptor());
System.out.println("入參[名稱(chēng)]:" + attr.variableName(1) + "," + attr.variableName(2));
System.out.println("入參[類(lèi)型]:" + parameterTypes[0].getName() + "," + parameterTypes[1].getName());
System.out.println("出參[類(lèi)型]:" + returnTypeName);
  輸出結果
  類(lèi)名:org.itstack.demo.javassist.ApiTest
方法:strToInt
類(lèi)型:非靜態(tài)方法
描述:(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Integer;
入參[名稱(chēng)]:str01,str02
入參[類(lèi)型]:java.lang.String,java.lang.String
出參[類(lèi)型]:java.lang.Integer
  以上,輸出信息為監控方法做準備。從上面可以記錄方法的基本描述和輸入參數的數量。尤其是入參的個(gè)數,因為后面需要用到$1來(lái)獲取沒(méi)有給入參的值。
  2. 方法字節碼檢測
  需要通過(guò)字節碼檢測來(lái)更改的原創(chuàng )方法;
  public class ApiTest {
public Integer strToInt(String str01, String str02) {
return Integer.parseInt(str01);
}
}
  2.1 先標記基礎屬性
  在監控的情況下,不可能將每次調用的所有方法信息都匯總輸出。這不僅僅是性能問(wèn)題,這些都是固定信息,不需要每次方法執行都輸出。
  這很好!然后在編譯方法時(shí),會(huì )為每個(gè)方法生成一個(gè)唯一的ID,并將方法的固定信息與ID關(guān)聯(lián)起來(lái)。也可以通過(guò)ID將監控數據傳遞到外部。
  // 方法:生成方法唯一標識ID
int idx = Monitor.generateMethodId(clazzName, methodName, parameterNameList, parameterTypeList, returnTypeName);
  生成ID的過(guò)程
  public static final int MAX_NUM = 1024 * 32;
private final static AtomicInteger index = new AtomicInteger(0);
private final static AtomicReferenceArray methodTagArr = new AtomicReferenceArray(MAX_NUM);
public static int generateMethodId(String clazzName, String methodName, List parameterNameList, List parameterTypeList, String returnType) {
MethodDescription methodDescription = new MethodDescription();
methodDescription.setClazzName(clazzName);
methodDescription.setMethodName(methodName);
methodDescription.setParameterNameList(parameterNameList);
methodDescription.setParameterTypeList(parameterTypeList);
methodDescription.setReturnType(returnType);
int methodId = index.getAndIncrement();
if (methodId > MAX_NUM) return -1;
methodTagArr.set(methodId, methodDescription);
return methodId;
}
  2.2 字節碼檢測增加入口方法時(shí)間
  // 定義屬性
ctMethod.addLocalVariable("startNanos", CtClass.longType);
// 方法前加強
ctMethod.insertBefore("{ startNanos = System.nanoTime(); }");
  final類(lèi)類(lèi)方法
  public class ApiTest {
public Integer strToInt(String str01, String str02) {
long startNanos = System.nanoTime();
return Integer.parseInt(str01);
}
}
  2.3 字節碼檢測添加輸入和輸出
  // 定義屬性
ctMethod.addLocalVariable("parameterValues", pool.get(Object[].class.getName()));
// 方法前加強
ctMethod.insertBefore("{ parameterValues = new Object[]{" + parameters.toString() + "}; }");
  final類(lèi)類(lèi)方法
  public Integer strToInt(String str01, String str02) {
Object[] var10000 = new Object[]{str01, str02};
long startNanos = System.nanoTime();
return Integer.parseInt(str01);
}
  2.4 定義監控方法
  因為我們需要向外部輸出監控信息。然后我們在這里定義一個(gè)靜態(tài)方法,讓字節碼增強的方法調用,并輸出監控信息。
  public static void point(final int methodId, final long startNanos, Object[] parameterValues, Object returnValues) {
MethodDescription method = methodTagArr.get(methodId);
System.out.println("監控 - Begin");
System.out.println("方法:" + method.getClazzName() + "." + method.getMethodName());
System.out.println("入參:" + JSON.toJSONString(method.getParameterNameList()) + " 入參[類(lèi)型]:" + JSON.toJSONString(method.getParameterTypeList()) + " 入數[值]:" + JSON.toJSONString(parameterValues));
System.out.println("出參:" + method.getReturnType() + " 出參[值]:" + JSON.toJSONString(returnValues));
System.out.println("耗時(shí):" + (System.nanoTime() - startNanos) / 1000000 + "(s)");
System.out.println("監控 - End\r\n");
}
public static void point(final int methodId, Throwable throwable) {
MethodDescription method = methodTagArr.get(methodId);
System.out.println("監控 - Begin");
System.out.println("方法:" + method.getClazzName() + "." + method.getMethodName());
System.out.println("異常:" + throwable.getMessage());
System.out.println("監控 - End\r\n");
}
  2.5 字節碼檢測調用監控方法
  // 方法后加強
ctMethod.insertAfter("{ org.itstack.demo.javassist.Monitor.point(" + idx + ", startNanos, parameterValues, $_);}", false); // 如果返回類(lèi)型非對象類(lèi)型,$_ 需要進(jìn)行類(lèi)型轉換
  final類(lèi)類(lèi)方法
  public Integer strToInt(String str01, String str02) {
Object[] parameterValues = new Object[]{str01, str02};
long startNanos = System.nanoTime();
Integer var7 = Integer.parseInt(str01);
Monitor.point(0, startNanos, parameterValues, var7);
return var7;
}
  2.6 字節碼檢測將 TryCatch 添加到方法中
  以上instrumentation內容,如果只是正常調用,是沒(méi)有問(wèn)題的。但是如果方法拋出異常,那么此時(shí)就無(wú)法采集到監控信息。所以你還需要將 TryCatch 添加到方法中。
  // 方法;添加TryCatch
ctMethod.addCatch("{ org.itstack.demo.javassist.Monitor.point(" + idx + ", $e); throw $e; }", ClassPool.getDefault().get("java.lang.Exception")); // 添加異常捕獲
  final類(lèi)類(lèi)方法
  public Integer strToInt(String str01, String str02) {
try {
Object[] parameterValues = new Object[]{str01, str02};
long startNanos = System.nanoTime();
Integer var7 = Integer.parseInt(str01);
Monitor.point(0, startNanos, parameterValues, var7);
return var7;
} catch (Exception var9) {
Monitor.point(0, var9);
throw var9;
}
}
  四、測試結果
  下一步是執行我們的調用來(lái)測試修改后的方法字節碼。通過(guò)不同的輸入參數驗證監測結果;
  // 測試調用
byte[] bytes = ctClass.toBytecode();
Class clazzNew = new GenerateClazzMethod().defineClass("org.itstack.demo.javassist.ApiTest", bytes, 0, bytes.length);
// 反射獲取 main 方法
Method method = clazzNew.getMethod("strToInt", String.class, String.class);
Object obj_01 = method.invoke(clazzNew.newInstance(), "1", "2");
System.out.println("正確入參:" + obj_01);
Object obj_02 = method.invoke(clazzNew.newInstance(), "a", "b");
System.out.println("異常入參:" + obj_02);
  測試結果
  監控 - Begin
方法:org.itstack.demo.javassist.ApiTest.strToInt
入參:["str01","str02"] 入參[類(lèi)型]:["java.lang.String","java.lang.String"] 入數[值]:["1","2"]
出參:java.lang.Integer 出參[值]:1
耗時(shí):63(s)
監控 - End
正確入參:1
監控 - Begin
方法:org.itstack.demo.javassist.ApiTest.strToInt
異常:For input string: "a"
監控 - End
  五、總結 查看全部

  文章采集調用(
開(kāi)發(fā)環(huán)境JDK1.8.0javassist本章本章GA本章涉及源碼的開(kāi)發(fā))
  
  一、前言
  字節碼編程插樁技術(shù)常結合Javaagent技術(shù)用于系統的非侵入式監控,可以替代方法中的硬編碼操作。例如,您需要監控一個(gè)方法,包括;方法信息、執行時(shí)間、輸入輸出參數、執行鏈接、異常。那么就非常適合用這樣的技術(shù)手段進(jìn)行加工。
  為了體現這部分的核心內容,本文將只使用Javassist技術(shù)對一段方法字節碼進(jìn)行instrument,最后輸出該方法的執行信息,如下;
  Method - 后續字節碼增強操作的測試方法
  public Integer strToInt(String str01, String str02) {
return Integer.parseInt(str01);
}
  監控 - 方法的字節碼增強后,輸出監控信息
  監控 - Begin
方法:org.itstack.demo.javassist.ApiTest.strToInt
入參:["str01","str02"] 入參[類(lèi)型]:["java.lang.String","java.lang.String"] 入數[值]:["1","2"]
出參:java.lang.Integer 出參[值]:1
耗時(shí):59(s)
監控 - End
  有了這樣的監控方案,我們基本上可以輸出方法執行過(guò)程中的所有信息。然后通過(guò)后期的改進(jìn),將監控信息顯示在界面上,并實(shí)時(shí)發(fā)出警報。不僅提高了系統的監控質(zhì)量,也便于研發(fā)排查和定位問(wèn)題。
  這很好!然后我們一步步開(kāi)始使用javassist進(jìn)行字節碼插樁,就達到了我們的監控效果。
  二、開(kāi)發(fā)環(huán)境JDK 1.8.0javassist 3.12.1.GA本章涉及的源碼為:itstack-demo-bytecode -1-04,可以關(guān)注公眾號:bugstack 蟲(chóng)洞棧,回復源碼下載即可。您將獲得下載鏈接列表。打開(kāi)后第十七期“因為我有很多開(kāi)源代碼”,記得給個(gè)Star!三、技術(shù)實(shí)現1. 獲取方法的基本信息1.1 獲取類(lèi)
  ClassPool pool = ClassPool.getDefault();
// 獲取類(lèi)
CtClass ctClass = pool.get(org.itstack.demo.javassist.ApiTest.class.getName());
ctClass.replaceClassName("ApiTest", "ApiTest02");
String clazzName = ctClass.getName();
  通過(guò)類(lèi)名獲取類(lèi)信息,這里可以替換類(lèi)名。它還包括一些其他操作來(lái)獲取類(lèi)中的屬性,例如;ctClass.getSimpleName()、ctClass.getAnnotations() 等等。
  1.2 如何獲得
  CtMethod ctMethod = ctClass.getDeclaredMethod("strToInt");
String methodName = ctMethod.getName();
  通過(guò)getDeclaredMethod獲取方法的CtMethod的內容。之后,您可以獲取方法名稱(chēng)等信息。
  1.3 方法信息
  MethodInfo methodInfo = ctMethod.getMethodInfo();
  MethodInfo 收錄方法信息;名稱(chēng)、類(lèi)型等
  1.4 種方法類(lèi)型
  boolean isStatic = (methodInfo.getAccessFlags() & AccessFlag.STATIC) != 0;
  通過(guò)methodInfo.getAccessFlags()獲取方法的標識符,然后使用AND運算AccessFlag.STATIC判斷該方法是否為靜態(tài)方法。因為靜態(tài)方法會(huì )影響后續參數名的獲取,所以靜態(tài)方法的第一個(gè)參數就是this,需要排除。
  1.5 方法:輸入參數信息{name and type}
  CodeAttribute codeAttribute = methodInfo.getCodeAttribute();
LocalVariableAttribute attr = (LocalVariableAttribute) codeAttribute.getAttribute(LocalVariableAttribute.tag);
CtClass[] parameterTypes = ctMethod.getParameterTypes();
  1.6 方法;參數信息
  CtClass returnType = ctMethod.getReturnType();
String returnTypeName = returnType.getName();
  對于方法的參數信息,只需要獲取參數類(lèi)型即可。
  1.7 輸出所有獲取的信息
  System.out.println("類(lèi)名:" + clazzName);
System.out.println("方法:" + methodName);
System.out.println("類(lèi)型:" + (isStatic ? "靜態(tài)方法" : "非靜態(tài)方法"));
System.out.println("描述:" + methodInfo.getDescriptor());
System.out.println("入參[名稱(chēng)]:" + attr.variableName(1) + "," + attr.variableName(2));
System.out.println("入參[類(lèi)型]:" + parameterTypes[0].getName() + "," + parameterTypes[1].getName());
System.out.println("出參[類(lèi)型]:" + returnTypeName);
  輸出結果
  類(lèi)名:org.itstack.demo.javassist.ApiTest
方法:strToInt
類(lèi)型:非靜態(tài)方法
描述:(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Integer;
入參[名稱(chēng)]:str01,str02
入參[類(lèi)型]:java.lang.String,java.lang.String
出參[類(lèi)型]:java.lang.Integer
  以上,輸出信息為監控方法做準備。從上面可以記錄方法的基本描述和輸入參數的數量。尤其是入參的個(gè)數,因為后面需要用到$1來(lái)獲取沒(méi)有給入參的值。
  2. 方法字節碼檢測
  需要通過(guò)字節碼檢測來(lái)更改的原創(chuàng )方法;
  public class ApiTest {
public Integer strToInt(String str01, String str02) {
return Integer.parseInt(str01);
}
}
  2.1 先標記基礎屬性
  在監控的情況下,不可能將每次調用的所有方法信息都匯總輸出。這不僅僅是性能問(wèn)題,這些都是固定信息,不需要每次方法執行都輸出。
  這很好!然后在編譯方法時(shí),會(huì )為每個(gè)方法生成一個(gè)唯一的ID,并將方法的固定信息與ID關(guān)聯(lián)起來(lái)。也可以通過(guò)ID將監控數據傳遞到外部。
  // 方法:生成方法唯一標識ID
int idx = Monitor.generateMethodId(clazzName, methodName, parameterNameList, parameterTypeList, returnTypeName);
  生成ID的過(guò)程
  public static final int MAX_NUM = 1024 * 32;
private final static AtomicInteger index = new AtomicInteger(0);
private final static AtomicReferenceArray methodTagArr = new AtomicReferenceArray(MAX_NUM);
public static int generateMethodId(String clazzName, String methodName, List parameterNameList, List parameterTypeList, String returnType) {
MethodDescription methodDescription = new MethodDescription();
methodDescription.setClazzName(clazzName);
methodDescription.setMethodName(methodName);
methodDescription.setParameterNameList(parameterNameList);
methodDescription.setParameterTypeList(parameterTypeList);
methodDescription.setReturnType(returnType);
int methodId = index.getAndIncrement();
if (methodId > MAX_NUM) return -1;
methodTagArr.set(methodId, methodDescription);
return methodId;
}
  2.2 字節碼檢測增加入口方法時(shí)間
  // 定義屬性
ctMethod.addLocalVariable("startNanos", CtClass.longType);
// 方法前加強
ctMethod.insertBefore("{ startNanos = System.nanoTime(); }");
  final類(lèi)類(lèi)方法
  public class ApiTest {
public Integer strToInt(String str01, String str02) {
long startNanos = System.nanoTime();
return Integer.parseInt(str01);
}
}
  2.3 字節碼檢測添加輸入和輸出
  // 定義屬性
ctMethod.addLocalVariable("parameterValues", pool.get(Object[].class.getName()));
// 方法前加強
ctMethod.insertBefore("{ parameterValues = new Object[]{" + parameters.toString() + "}; }");
  final類(lèi)類(lèi)方法
  public Integer strToInt(String str01, String str02) {
Object[] var10000 = new Object[]{str01, str02};
long startNanos = System.nanoTime();
return Integer.parseInt(str01);
}
  2.4 定義監控方法
  因為我們需要向外部輸出監控信息。然后我們在這里定義一個(gè)靜態(tài)方法,讓字節碼增強的方法調用,并輸出監控信息。
  public static void point(final int methodId, final long startNanos, Object[] parameterValues, Object returnValues) {
MethodDescription method = methodTagArr.get(methodId);
System.out.println("監控 - Begin");
System.out.println("方法:" + method.getClazzName() + "." + method.getMethodName());
System.out.println("入參:" + JSON.toJSONString(method.getParameterNameList()) + " 入參[類(lèi)型]:" + JSON.toJSONString(method.getParameterTypeList()) + " 入數[值]:" + JSON.toJSONString(parameterValues));
System.out.println("出參:" + method.getReturnType() + " 出參[值]:" + JSON.toJSONString(returnValues));
System.out.println("耗時(shí):" + (System.nanoTime() - startNanos) / 1000000 + "(s)");
System.out.println("監控 - End\r\n");
}
public static void point(final int methodId, Throwable throwable) {
MethodDescription method = methodTagArr.get(methodId);
System.out.println("監控 - Begin");
System.out.println("方法:" + method.getClazzName() + "." + method.getMethodName());
System.out.println("異常:" + throwable.getMessage());
System.out.println("監控 - End\r\n");
}
  2.5 字節碼檢測調用監控方法
  // 方法后加強
ctMethod.insertAfter("{ org.itstack.demo.javassist.Monitor.point(" + idx + ", startNanos, parameterValues, $_);}", false); // 如果返回類(lèi)型非對象類(lèi)型,$_ 需要進(jìn)行類(lèi)型轉換
  final類(lèi)類(lèi)方法
  public Integer strToInt(String str01, String str02) {
Object[] parameterValues = new Object[]{str01, str02};
long startNanos = System.nanoTime();
Integer var7 = Integer.parseInt(str01);
Monitor.point(0, startNanos, parameterValues, var7);
return var7;
}
  2.6 字節碼檢測將 TryCatch 添加到方法中
  以上instrumentation內容,如果只是正常調用,是沒(méi)有問(wèn)題的。但是如果方法拋出異常,那么此時(shí)就無(wú)法采集到監控信息。所以你還需要將 TryCatch 添加到方法中。
  // 方法;添加TryCatch
ctMethod.addCatch("{ org.itstack.demo.javassist.Monitor.point(" + idx + ", $e); throw $e; }", ClassPool.getDefault().get("java.lang.Exception")); // 添加異常捕獲
  final類(lèi)類(lèi)方法
  public Integer strToInt(String str01, String str02) {
try {
Object[] parameterValues = new Object[]{str01, str02};
long startNanos = System.nanoTime();
Integer var7 = Integer.parseInt(str01);
Monitor.point(0, startNanos, parameterValues, var7);
return var7;
} catch (Exception var9) {
Monitor.point(0, var9);
throw var9;
}
}
  四、測試結果
  下一步是執行我們的調用來(lái)測試修改后的方法字節碼。通過(guò)不同的輸入參數驗證監測結果;
  // 測試調用
byte[] bytes = ctClass.toBytecode();
Class clazzNew = new GenerateClazzMethod().defineClass("org.itstack.demo.javassist.ApiTest", bytes, 0, bytes.length);
// 反射獲取 main 方法
Method method = clazzNew.getMethod("strToInt", String.class, String.class);
Object obj_01 = method.invoke(clazzNew.newInstance(), "1", "2");
System.out.println("正確入參:" + obj_01);
Object obj_02 = method.invoke(clazzNew.newInstance(), "a", "b");
System.out.println("異常入參:" + obj_02);
  測試結果
  監控 - Begin
方法:org.itstack.demo.javassist.ApiTest.strToInt
入參:["str01","str02"] 入參[類(lèi)型]:["java.lang.String","java.lang.String"] 入數[值]:["1","2"]
出參:java.lang.Integer 出參[值]:1
耗時(shí):63(s)
監控 - End
正確入參:1
監控 - Begin
方法:org.itstack.demo.javassist.ApiTest.strToInt
異常:For input string: "a"
監控 - End
  五、總結

文章采集調用(優(yōu)采云采集+偽原創(chuàng )錯誤博客分享《《》)

采集交流 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 138 次瀏覽 ? 2022-04-13 05:18 ? 來(lái)自相關(guān)話(huà)題

  文章采集調用(優(yōu)采云采集+偽原創(chuàng )錯誤博客分享《《》)
  優(yōu)采云 是一個(gè)非常有用的文章采集 工具,但它也是一個(gè)很多人不知道的文章 構建工具。優(yōu)采云采集+偽原創(chuàng ) 方法已經(jīng)流行了這么多年,仍然被大量的人使用,構建 原創(chuàng )文章 將使網(wǎng)站 改變更好的質(zhì)量。今天,bug 博客( )分享了“優(yōu)采云采集如何量產(chǎn)原創(chuàng )文章”。我希望能有所幫助。
  優(yōu)采云構建原創(chuàng )文章
  一、優(yōu)采云采集+偽原創(chuàng )
  報錯博客先講優(yōu)采云采集偽原創(chuàng )的操作方法。查找更好的信息網(wǎng)站采集一些較新的文章、采集有互聯(lián)網(wǎng)熱詞,如百度搜索熱點(diǎn)、抖音熱點(diǎn)、微信博熱搜和很快。
  標題不要重復,不建議直接偽原創(chuàng )標題。最好手動(dòng)編輯標題。內容 偽原創(chuàng ) 應該是可讀的。如果不可讀,不建議使用那種工具,因為這個(gè)內容已經(jīng)發(fā)了很久了,網(wǎng)站活不了多久了。
  優(yōu)采云采集+偽原創(chuàng )的形式確實(shí)可以創(chuàng )作很多內容,但是也應該考慮在網(wǎng)站中發(fā)布一些原創(chuàng )文章提高百度信心,讓您事半功倍。
  二、優(yōu)采云構建原創(chuàng )文章
  與其 優(yōu)采云 構造 原創(chuàng )文章 不如調用內容,然后使用 文章 正文內容格式調用那些單詞和句子。如何將這些單詞和句子很好地呈現給用戶(hù)和搜索引擎,不僅具有一定的可讀性,而且具有看似實(shí)用的功能。這是錯誤博客的示例。當 愛(ài)站 網(wǎng)絡(luò )對 網(wǎng)站 進(jìn)行數據查詢(xún)時(shí),該頁(yè)面是一個(gè)類(lèi)似于 原創(chuàng )文章 的新頁(yè)面,通過(guò)調用各種數據形成。頁(yè)面,這樣的頁(yè)面有很好的排名。當這種頁(yè)面出現在搜索引擎中時(shí),很多人會(huì )選擇點(diǎn)擊,而且可能會(huì )停留很長(cháng)時(shí)間。這是一個(gè)成功的案例。
  當然,錯誤博客并沒(méi)有那么有能力做出這樣一種形式的頁(yè)面來(lái)調用各種數據,但是我們可以根據自己的能力來(lái)構建這樣一個(gè)原創(chuàng )頁(yè)面,這樣大量的內容頁(yè)面就會(huì )不被我們使用。搜索引擎的罷工也可能會(huì )受到鼓勵,畢竟這個(gè)頁(yè)面非常實(shí)用。 查看全部

  文章采集調用(優(yōu)采云采集+偽原創(chuàng )錯誤博客分享《《》)
  優(yōu)采云 是一個(gè)非常有用的文章采集 工具,但它也是一個(gè)很多人不知道的文章 構建工具。優(yōu)采云采集+偽原創(chuàng ) 方法已經(jīng)流行了這么多年,仍然被大量的人使用,構建 原創(chuàng )文章 將使網(wǎng)站 改變更好的質(zhì)量。今天,bug 博客( )分享了“優(yōu)采云采集如何量產(chǎn)原創(chuàng )文章”。我希望能有所幫助。
  優(yōu)采云構建原創(chuàng )文章
  一、優(yōu)采云采集+偽原創(chuàng )
  報錯博客先講優(yōu)采云采集偽原創(chuàng )的操作方法。查找更好的信息網(wǎng)站采集一些較新的文章、采集有互聯(lián)網(wǎng)熱詞,如百度搜索熱點(diǎn)、抖音熱點(diǎn)、微信博熱搜和很快。
  標題不要重復,不建議直接偽原創(chuàng )標題。最好手動(dòng)編輯標題。內容 偽原創(chuàng ) 應該是可讀的。如果不可讀,不建議使用那種工具,因為這個(gè)內容已經(jīng)發(fā)了很久了,網(wǎng)站活不了多久了。
  優(yōu)采云采集+偽原創(chuàng )的形式確實(shí)可以創(chuàng )作很多內容,但是也應該考慮在網(wǎng)站中發(fā)布一些原創(chuàng )文章提高百度信心,讓您事半功倍。
  二、優(yōu)采云構建原創(chuàng )文章
  與其 優(yōu)采云 構造 原創(chuàng )文章 不如調用內容,然后使用 文章 正文內容格式調用那些單詞和句子。如何將這些單詞和句子很好地呈現給用戶(hù)和搜索引擎,不僅具有一定的可讀性,而且具有看似實(shí)用的功能。這是錯誤博客的示例。當 愛(ài)站 網(wǎng)絡(luò )對 網(wǎng)站 進(jìn)行數據查詢(xún)時(shí),該頁(yè)面是一個(gè)類(lèi)似于 原創(chuàng )文章 的新頁(yè)面,通過(guò)調用各種數據形成。頁(yè)面,這樣的頁(yè)面有很好的排名。當這種頁(yè)面出現在搜索引擎中時(shí),很多人會(huì )選擇點(diǎn)擊,而且可能會(huì )停留很長(cháng)時(shí)間。這是一個(gè)成功的案例。
  當然,錯誤博客并沒(méi)有那么有能力做出這樣一種形式的頁(yè)面來(lái)調用各種數據,但是我們可以根據自己的能力來(lái)構建這樣一個(gè)原創(chuàng )頁(yè)面,這樣大量的內容頁(yè)面就會(huì )不被我們使用。搜索引擎的罷工也可能會(huì )受到鼓勵,畢竟這個(gè)頁(yè)面非常實(shí)用。

文章采集調用(R語(yǔ)言爬蟲(chóng)格式的json格式,尋找新的方法!)

采集交流 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 143 次瀏覽 ? 2022-04-12 19:35 ? 來(lái)自相關(guān)話(huà)題

  文章采集調用(R語(yǔ)言爬蟲(chóng)格式的json格式,尋找新的方法!)
  ==========背景===================
  最近一直在用R語(yǔ)言爬,但是有些網(wǎng)站是動(dòng)態(tài)json格式的。每次都找到重定向的 URL 很麻煩。因此,我正在尋找一種新方法,構建一個(gè)瀏覽器,在瀏覽器中查找 URL。于是出現了以下問(wèn)題:
  ==========執行步驟分割線(xiàn)============
  1、cmd enable java -jar selenium-server-standalone-2.53.0.jar //啟動(dòng)selenium
  2、R 控制臺
  > library("Rwebdriver", lib.loc="C:/Program Files/R/R-3.2.3/library")
  加載所需的包:RCurl
  加載所需的包:bitops
  加載所需包:RJSONIO
  > library("XML", lib.loc="\\\\CNDOUW0000/Users/CNLeeWi/R/win-library/3.2")
  > start_session(root = "" ,browser = "firefox")
  函數錯誤(類(lèi)型、msg、asError = TRUE):
  無(wú)法連接到 localhost 端口 80:連接被拒絕
  ==========相關(guān)信息鏈接================== 查看全部

  文章采集調用(R語(yǔ)言爬蟲(chóng)格式的json格式,尋找新的方法!)
  ==========背景===================
  最近一直在用R語(yǔ)言爬,但是有些網(wǎng)站是動(dòng)態(tài)json格式的。每次都找到重定向的 URL 很麻煩。因此,我正在尋找一種新方法,構建一個(gè)瀏覽器,在瀏覽器中查找 URL。于是出現了以下問(wèn)題:
  ==========執行步驟分割線(xiàn)============
  1、cmd enable java -jar selenium-server-standalone-2.53.0.jar //啟動(dòng)selenium
  2、R 控制臺
  > library("Rwebdriver", lib.loc="C:/Program Files/R/R-3.2.3/library")
  加載所需的包:RCurl
  加載所需的包:bitops
  加載所需包:RJSONIO
  > library("XML", lib.loc="\\\\CNDOUW0000/Users/CNLeeWi/R/win-library/3.2")
  > start_session(root = "" ,browser = "firefox")
  函數錯誤(類(lèi)型、msg、asError = TRUE):
  無(wú)法連接到 localhost 端口 80:連接被拒絕
  ==========相關(guān)信息鏈接==================

文章采集調用(天弘基金(余額寶)移動(dòng)平臺首席架構師負責人)

采集交流 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 127 次瀏覽 ? 2022-04-12 17:31 ? 來(lái)自相關(guān)話(huà)題

  文章采集調用(天弘基金(余額寶)移動(dòng)平臺首席架構師負責人)
  近年來(lái),APM進(jìn)入了快速發(fā)展的快車(chē)道。作為APM的核心功能,分布式環(huán)境下的自動(dòng)應用發(fā)現和動(dòng)態(tài)調用鏈路分析也被廣泛應用于A(yíng)PM的推廣。一些不足暴露出來(lái):完全基于運行狀態(tài)的分析模式?jīng)Q定了只能獲取與實(shí)際調用的邏輯鏈接,大量未被掩埋或未被觸發(fā)的調用邏輯成為無(wú)法觸及的“失落的世界” . 撞。找到這部分“失落的世界”對于我們了解分布式環(huán)境中應用程序的全貌非常重要。天鴻基金移動(dòng)平臺團隊在這方面進(jìn)行了一些創(chuàng )新探索。我們跳出了傳統APM的慣性思維,掃描分析海量代碼中的調用關(guān)系,得到分布式環(huán)境下“前中后”站的完整調用鏈,并在此基礎上疊加動(dòng)態(tài)調用鏈,構建精細化APM監控。通過(guò)這個(gè)話(huà)題,我將結合我們的實(shí)踐,詳細介紹“靜態(tài)調用鏈路發(fā)現”的技術(shù)和手段,并探討如何在運維和開(kāi)發(fā)場(chǎng)景中將其與現有的APM能力相結合。--&gt;觀(guān)眾受益:1、了解分布式環(huán)境下APM的“優(yōu)”與“差”。2、了解構建“靜態(tài)呼叫鏈路發(fā)現”能力的技術(shù)和手段。3、 學(xué)習如何用創(chuàng )新思維拓展APM的應用場(chǎng)景。--&gt; 個(gè)人介紹:天弘基金(月寶)移動(dòng)平臺首席架構師李鑫,負責移動(dòng)平臺整體技術(shù)架構設計。曾任當當網(wǎng)架構師,負責電商后端運營(yíng)產(chǎn)品平臺整體技術(shù)架構及研發(fā)團隊管理;華為云計算專(zhuān)家,主導華為軟件各類(lèi)云計算產(chǎn)品和服務(wù)的設計、規劃和建設。個(gè)人技術(shù)涉及大規模分布式應用與治理、中間件云化與服務(wù)化(PaaS)、APM監控、基礎開(kāi)發(fā)平臺等領(lǐng)域, 查看全部

  文章采集調用(天弘基金(余額寶)移動(dòng)平臺首席架構師負責人)
  近年來(lái),APM進(jìn)入了快速發(fā)展的快車(chē)道。作為APM的核心功能,分布式環(huán)境下的自動(dòng)應用發(fā)現和動(dòng)態(tài)調用鏈路分析也被廣泛應用于A(yíng)PM的推廣。一些不足暴露出來(lái):完全基于運行狀態(tài)的分析模式?jīng)Q定了只能獲取與實(shí)際調用的邏輯鏈接,大量未被掩埋或未被觸發(fā)的調用邏輯成為無(wú)法觸及的“失落的世界” . 撞。找到這部分“失落的世界”對于我們了解分布式環(huán)境中應用程序的全貌非常重要。天鴻基金移動(dòng)平臺團隊在這方面進(jìn)行了一些創(chuàng )新探索。我們跳出了傳統APM的慣性思維,掃描分析海量代碼中的調用關(guān)系,得到分布式環(huán)境下“前中后”站的完整調用鏈,并在此基礎上疊加動(dòng)態(tài)調用鏈,構建精細化APM監控。通過(guò)這個(gè)話(huà)題,我將結合我們的實(shí)踐,詳細介紹“靜態(tài)調用鏈路發(fā)現”的技術(shù)和手段,并探討如何在運維和開(kāi)發(fā)場(chǎng)景中將其與現有的APM能力相結合。--&gt;觀(guān)眾受益:1、了解分布式環(huán)境下APM的“優(yōu)”與“差”。2、了解構建“靜態(tài)呼叫鏈路發(fā)現”能力的技術(shù)和手段。3、 學(xué)習如何用創(chuàng )新思維拓展APM的應用場(chǎng)景。--&gt; 個(gè)人介紹:天弘基金(月寶)移動(dòng)平臺首席架構師李鑫,負責移動(dòng)平臺整體技術(shù)架構設計。曾任當當網(wǎng)架構師,負責電商后端運營(yíng)產(chǎn)品平臺整體技術(shù)架構及研發(fā)團隊管理;華為云計算專(zhuān)家,主導華為軟件各類(lèi)云計算產(chǎn)品和服務(wù)的設計、規劃和建設。個(gè)人技術(shù)涉及大規模分布式應用與治理、中間件云化與服務(wù)化(PaaS)、APM監控、基礎開(kāi)發(fā)平臺等領(lǐng)域,

文章采集調用(一個(gè)企業(yè)網(wǎng)站被百度降權了怎么辦?(圖))

采集交流 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 134 次瀏覽 ? 2022-04-12 06:32 ? 來(lái)自相關(guān)話(huà)題

  文章采集調用(一個(gè)企業(yè)網(wǎng)站被百度降權了怎么辦?(圖))
  去年年底,一位客戶(hù)要求我幫助創(chuàng )建一家公司網(wǎng)站??紤]到 網(wǎng)站 將來(lái)會(huì )推廣搜索引擎,網(wǎng)站 在 SEO 中必須是搜索引擎友好的。最后我選擇了DeDecms,它可以在URL、PageTitle、TextBlock、LinkBlock、Auto Sitemap、Related Article中做早期的SEO布局。所以在欄目規劃、版面設計、模板制作階段,我將各種SEO元素充分融入到整個(gè)制作階段,希望網(wǎng)站上線(xiàn)后,能夠快速積累搜索排名權重。尤其是在模板代碼編寫(xiě)方面,可以有效控制鏈接輸出和導入,盡可能提高內部鏈接的相關(guān)性和關(guān)鍵詞的匹配位置,去除無(wú)用的網(wǎng)頁(yè)噪音信息,
  果然,網(wǎng)站正式發(fā)布后,網(wǎng)站收錄的占比迅速達到70%,大部分產(chǎn)品終端頁(yè)面為收錄,部分信息頁(yè)面為收錄 ,更重要的是:行業(yè)關(guān)鍵詞排名和產(chǎn)品關(guān)鍵詞排名進(jìn)步很快;整個(gè)網(wǎng)站在SEO運營(yíng)中呈現良性發(fā)展態(tài)勢??蛻?hù)端開(kāi)始接管網(wǎng)站并正常更新站點(diǎn)內容,按照設定的時(shí)間表,一切應該都進(jìn)行得很順利。
  不過(guò)最近網(wǎng)站SEO的表現開(kāi)始下滑,網(wǎng)頁(yè)數量收錄首當其沖。百度統計后臺顯示的頁(yè)面索引與搜索框中site命令返回的結果數量有顯著(zhù)差異。site 命令顯示 Only 2 pages are 收錄,都是首頁(yè),首頁(yè)有 www 和沒(méi)有 www 的兩個(gè)版本。另外,信息正常更新后,百度索引很快,短時(shí)間內可以通過(guò)site命令返回結果,但過(guò)了一會(huì )兒發(fā)現收錄無(wú)效?;谝陨锨闆r,我認為網(wǎng)站已經(jīng)被百度降級了。
  為了找到問(wèn)題所在,我研究了各種因素,發(fā)現:
 ?。?)除了正常更新網(wǎng)站的內容外,企業(yè)端也在積極運營(yíng)外鏈,建外鏈是好事,但是用錯了方式參與資源站的鏈輪;
 ?。?)網(wǎng)上有相同模板、相同內容、不同品牌的仿站,而百度上的仿站收錄也只有首頁(yè),“驚人的相似” ”給客戶(hù)網(wǎng)站。
  1、關(guān)于鏈輪問(wèn)題,幸好我及時(shí)發(fā)現并制止了這種行為。由于參與sprocket的產(chǎn)品頁(yè)面只有幾個(gè),時(shí)間不長(cháng),應該不會(huì )有這么大的影響,更何況自己的資源站。.
  2、關(guān)于重復站點(diǎn),非常少見(jiàn)。大多數人會(huì )自覺(jué)地在網(wǎng)站內??容或組織形式上形成差異;而如果客戶(hù)網(wǎng)站有這樣的SEO癥狀,恐怕關(guān)鍵就在于仿網(wǎng)站,當我看到仿網(wǎng)站的時(shí)候,我完全無(wú)語(yǔ)了。除了公司的品牌名稱(chēng)不同,網(wǎng)站我都太了解了;本來(lái)想吐槽的,但回頭看,現在網(wǎng)絡(luò )不流行了。是不是到處都有抄襲的趨勢?或許習慣了就好,但我不能忍受的是模板100%模仿,數據完整采集沒(méi)事,拜托,你敢不敢放是99 % 相同的網(wǎng)站作為一個(gè)整體發(fā)布?你TMD搞SEO,不知道類(lèi)似網(wǎng)站!你的TMD模仿站也可以模仿我過(guò)去寫(xiě)的自動(dòng)更新的網(wǎng)站地圖文件sitemap.php!做SEO傷不起啊。
  吐槽回吐槽,問(wèn)題還是要解決,采用了幾個(gè)方法:
  1、調整模板數據調用規則和新內容塊布局
  新的內容塊會(huì )使頁(yè)面主題關(guān)鍵詞更加分散,并調整數據調用規則,使仿站點(diǎn)的數據與自己頁(yè)面的數據不同,減少復制網(wǎng)站的負面影響@>搜索引擎優(yōu)化問(wèn)題。
  2、想辦法阻止內容采集
  DeDecms本身就有防止采集混淆字符串的功能,但是這種防止采集的方法對SEO來(lái)說(shuō)是非常不利的。您不希望搜索蜘蛛看到網(wǎng)頁(yè)中有許多隱藏的隱藏對象。文字,而這些文字會(huì )影響蜘蛛對信息塊主題的判斷,影響關(guān)鍵詞的排名。事實(shí)上,DeDecms并沒(méi)有根本的辦法來(lái)阻止采集,而且是一尺高。高一章,只要通過(guò)頁(yè)面發(fā)布你的信息,總能找到采集的方法;我根據網(wǎng)上搜集的資料采用了兩種方法,只能放最基本的采集。&gt;:
  (1)方法一:復制網(wǎng)頁(yè)正文內容時(shí)自動(dòng)添加版權信息
  JavaScript 代碼
  將上面的代碼放在文章頁(yè)面模板中文本末尾之后。這個(gè)方法我測試過(guò),只對IE瀏覽器有效,對火狐、傲游、谷歌瀏覽器無(wú)效。
  (2)方法二:使頁(yè)面代碼唯一
  一般別人采集時(shí),要獲取內容的起始碼和結束碼,而且必須是唯一的,所以填寫(xiě)的起始碼多為:
  . 這樣,我們在這個(gè)類(lèi)后面加上文章的ID值,改成這個(gè)
  ,其中{dede:field.id/}獲取dedecms中當前文章的ID值,那么每個(gè)生成的文章的ID值都不一樣,這里的起始代碼為也不同,所以其他人將無(wú)法采集,并且您一次只能選擇一件。
  當我們制作模板時(shí),在body標簽附近
  變成
  ,注意空格+{dede:field.id/},所以div的class沒(méi)有變,但是
  ,此代碼在每個(gè)文章的內容頁(yè)面中是唯一的,或者在html標簽中插入id={dede:field.id/},例如:
  并且,這里的{dede:field.id/}是在dedecms中獲取當前文章的ID值,這樣別人就無(wú)法采集了,只有一個(gè)可以一次采集。當然,其他人可以使用過(guò)濾規則來(lái)移除,但是如果我在所有類(lèi)中插入文檔ID,或者插入id=文檔ID。然后他只能采集整個(gè)頁(yè)面,然后過(guò)濾,使得采集更加復雜。
  缺點(diǎn):如果{dede:field.id/}插入的不夠多,其他人可以用過(guò)濾規則過(guò)濾掉。但是對于一些站群采集軟件來(lái)說(shuō),這個(gè)招數就足以阻止他們采集了!
  3、升級DeDecms到最新版本
  DeDecms老版本有漏洞,很容易被黑,要么嵌入各種廣告代碼,要么無(wú)緣無(wú)故添加太多隱藏鏈接,所以一定要升級到最新版本。
  上一篇:織夢(mèng)cms:錯誤的解決方法:check Snooping out of bounds
  下一步:設置dedecms標簽[field:global.autoindex/]的初始值 查看全部

  文章采集調用(一個(gè)企業(yè)網(wǎng)站被百度降權了怎么辦?(圖))
  去年年底,一位客戶(hù)要求我幫助創(chuàng )建一家公司網(wǎng)站??紤]到 網(wǎng)站 將來(lái)會(huì )推廣搜索引擎,網(wǎng)站 在 SEO 中必須是搜索引擎友好的。最后我選擇了DeDecms,它可以在URL、PageTitle、TextBlock、LinkBlock、Auto Sitemap、Related Article中做早期的SEO布局。所以在欄目規劃、版面設計、模板制作階段,我將各種SEO元素充分融入到整個(gè)制作階段,希望網(wǎng)站上線(xiàn)后,能夠快速積累搜索排名權重。尤其是在模板代碼編寫(xiě)方面,可以有效控制鏈接輸出和導入,盡可能提高內部鏈接的相關(guān)性和關(guān)鍵詞的匹配位置,去除無(wú)用的網(wǎng)頁(yè)噪音信息,
  果然,網(wǎng)站正式發(fā)布后,網(wǎng)站收錄的占比迅速達到70%,大部分產(chǎn)品終端頁(yè)面為收錄,部分信息頁(yè)面為收錄 ,更重要的是:行業(yè)關(guān)鍵詞排名和產(chǎn)品關(guān)鍵詞排名進(jìn)步很快;整個(gè)網(wǎng)站在SEO運營(yíng)中呈現良性發(fā)展態(tài)勢??蛻?hù)端開(kāi)始接管網(wǎng)站并正常更新站點(diǎn)內容,按照設定的時(shí)間表,一切應該都進(jìn)行得很順利。
  不過(guò)最近網(wǎng)站SEO的表現開(kāi)始下滑,網(wǎng)頁(yè)數量收錄首當其沖。百度統計后臺顯示的頁(yè)面索引與搜索框中site命令返回的結果數量有顯著(zhù)差異。site 命令顯示 Only 2 pages are 收錄,都是首頁(yè),首頁(yè)有 www 和沒(méi)有 www 的兩個(gè)版本。另外,信息正常更新后,百度索引很快,短時(shí)間內可以通過(guò)site命令返回結果,但過(guò)了一會(huì )兒發(fā)現收錄無(wú)效?;谝陨锨闆r,我認為網(wǎng)站已經(jīng)被百度降級了。
  為了找到問(wèn)題所在,我研究了各種因素,發(fā)現:
 ?。?)除了正常更新網(wǎng)站的內容外,企業(yè)端也在積極運營(yíng)外鏈,建外鏈是好事,但是用錯了方式參與資源站的鏈輪;
 ?。?)網(wǎng)上有相同模板、相同內容、不同品牌的仿站,而百度上的仿站收錄也只有首頁(yè),“驚人的相似” ”給客戶(hù)網(wǎng)站。
  1、關(guān)于鏈輪問(wèn)題,幸好我及時(shí)發(fā)現并制止了這種行為。由于參與sprocket的產(chǎn)品頁(yè)面只有幾個(gè),時(shí)間不長(cháng),應該不會(huì )有這么大的影響,更何況自己的資源站。.
  2、關(guān)于重復站點(diǎn),非常少見(jiàn)。大多數人會(huì )自覺(jué)地在網(wǎng)站內??容或組織形式上形成差異;而如果客戶(hù)網(wǎng)站有這樣的SEO癥狀,恐怕關(guān)鍵就在于仿網(wǎng)站,當我看到仿網(wǎng)站的時(shí)候,我完全無(wú)語(yǔ)了。除了公司的品牌名稱(chēng)不同,網(wǎng)站我都太了解了;本來(lái)想吐槽的,但回頭看,現在網(wǎng)絡(luò )不流行了。是不是到處都有抄襲的趨勢?或許習慣了就好,但我不能忍受的是模板100%模仿,數據完整采集沒(méi)事,拜托,你敢不敢放是99 % 相同的網(wǎng)站作為一個(gè)整體發(fā)布?你TMD搞SEO,不知道類(lèi)似網(wǎng)站!你的TMD模仿站也可以模仿我過(guò)去寫(xiě)的自動(dòng)更新的網(wǎng)站地圖文件sitemap.php!做SEO傷不起啊。
  吐槽回吐槽,問(wèn)題還是要解決,采用了幾個(gè)方法:
  1、調整模板數據調用規則和新內容塊布局
  新的內容塊會(huì )使頁(yè)面主題關(guān)鍵詞更加分散,并調整數據調用規則,使仿站點(diǎn)的數據與自己頁(yè)面的數據不同,減少復制網(wǎng)站的負面影響@>搜索引擎優(yōu)化問(wèn)題。
  2、想辦法阻止內容采集
  DeDecms本身就有防止采集混淆字符串的功能,但是這種防止采集的方法對SEO來(lái)說(shuō)是非常不利的。您不希望搜索蜘蛛看到網(wǎng)頁(yè)中有許多隱藏的隱藏對象。文字,而這些文字會(huì )影響蜘蛛對信息塊主題的判斷,影響關(guān)鍵詞的排名。事實(shí)上,DeDecms并沒(méi)有根本的辦法來(lái)阻止采集,而且是一尺高。高一章,只要通過(guò)頁(yè)面發(fā)布你的信息,總能找到采集的方法;我根據網(wǎng)上搜集的資料采用了兩種方法,只能放最基本的采集。&gt;:
  (1)方法一:復制網(wǎng)頁(yè)正文內容時(shí)自動(dòng)添加版權信息
  JavaScript 代碼
  將上面的代碼放在文章頁(yè)面模板中文本末尾之后。這個(gè)方法我測試過(guò),只對IE瀏覽器有效,對火狐、傲游、谷歌瀏覽器無(wú)效。
  (2)方法二:使頁(yè)面代碼唯一
  一般別人采集時(shí),要獲取內容的起始碼和結束碼,而且必須是唯一的,所以填寫(xiě)的起始碼多為:
  . 這樣,我們在這個(gè)類(lèi)后面加上文章的ID值,改成這個(gè)
  ,其中{dede:field.id/}獲取dedecms中當前文章的ID值,那么每個(gè)生成的文章的ID值都不一樣,這里的起始代碼為也不同,所以其他人將無(wú)法采集,并且您一次只能選擇一件。
  當我們制作模板時(shí),在body標簽附近
  變成
  ,注意空格+{dede:field.id/},所以div的class沒(méi)有變,但是
  ,此代碼在每個(gè)文章的內容頁(yè)面中是唯一的,或者在html標簽中插入id={dede:field.id/},例如:
  并且,這里的{dede:field.id/}是在dedecms中獲取當前文章的ID值,這樣別人就無(wú)法采集了,只有一個(gè)可以一次采集。當然,其他人可以使用過(guò)濾規則來(lái)移除,但是如果我在所有類(lèi)中插入文檔ID,或者插入id=文檔ID。然后他只能采集整個(gè)頁(yè)面,然后過(guò)濾,使得采集更加復雜。
  缺點(diǎn):如果{dede:field.id/}插入的不夠多,其他人可以用過(guò)濾規則過(guò)濾掉。但是對于一些站群采集軟件來(lái)說(shuō),這個(gè)招數就足以阻止他們采集了!
  3、升級DeDecms到最新版本
  DeDecms老版本有漏洞,很容易被黑,要么嵌入各種廣告代碼,要么無(wú)緣無(wú)故添加太多隱藏鏈接,所以一定要升級到最新版本。
  上一篇:織夢(mèng)cms:錯誤的解決方法:check Snooping out of bounds
  下一步:設置dedecms標簽[field:global.autoindex/]的初始值

文章采集調用(1.用python爬取代理批量采集實(shí)現方法:anyproxy+js)

采集交流 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 129 次瀏覽 ? 2022-04-11 13:02 ? 來(lái)自相關(guān)話(huà)題

  文章采集調用(1.用python爬取代理批量采集實(shí)現方法:anyproxy+js)
  微信公眾號文章爬取方法整理1.用python爬取
  php
  實(shí)現方法:通過(guò)微信提供的公眾號文章調用接口,實(shí)現抓取公眾號文章html的功能
  步驟:java
  1.需要安裝python selenium模塊包,使用selenium中的webdriver驅動(dòng)瀏覽器獲取cookies,達到登錄的效果;Python
  2.使用webdriver功能需要安裝對應瀏覽器的驅動(dòng)插件。我在這里使用谷歌瀏覽器進(jìn)行測試:
  谷歌瀏覽器版本是 52.0.2743.6 ;
  chromedriver版本為:V2.23
  注意:谷歌瀏覽器版本和chromedriver需要對應,否則啟動(dòng)時(shí)會(huì )報錯?!靖剑簊elenium的chromedriver和chrome版本映射表(更新為v2.30))】web
  3.微信公眾號登錄地址:chrome
  4.微信公眾號文章界面地址可以在微信公眾號后臺創(chuàng )建圖文信息,從超鏈接函數中獲?。簲祿?br />   5.搜索公眾號api
  6.獲取要爬取公眾號的fakeid瀏覽器
  7.選擇要爬取的公眾號,獲取文章接口地址微信
  8.文章列表翻頁(yè)和內容獲取
  2.AnyProxy 代理批量采集
  實(shí)現方式:anyproxy+js
  實(shí)現方式:anyproxy+java+webmagic
  3.FiddlerCore
  實(shí)現方式:抓包工具,Fiddler4
  經(jīng)過(guò)多個(gè)賬號的抓包分析,可以確認:
  _biz:這個(gè)14位的字符串是每一個(gè)公眾號的“id”,搜狗的微信平臺能夠得到
uin:與訪(fǎng)問(wèn)者有關(guān),微信號id
key:和所訪(fǎng)問(wèn)的公眾號有關(guān)
  步:
  1、編寫(xiě)按鈕向導腳本,在手機端自動(dòng)點(diǎn)擊公眾號文章的列表頁(yè)面,即“查看歷史消息”;
  2、使用fiddler代理劫持??手機訪(fǎng)問(wèn),將URL轉發(fā)到php編寫(xiě)的本地網(wǎng)頁(yè);
  3、將接收到的URL備份到php網(wǎng)頁(yè)上的數據庫中;
  4、使用python從數據庫中檢索URL,然后進(jìn)行正常爬取。
  在爬升過(guò)程中發(fā)現了一個(gè)問(wèn)題:
  如果只是想爬文章的內容,貌似沒(méi)有訪(fǎng)問(wèn)頻率限制,但是如果你想爬讀點(diǎn)贊數,達到一定頻率后,返回值會(huì )變成null,我設置的時(shí)間間隔為10秒,可以正常取到。在這個(gè)頻率下,一個(gè)小時(shí)只能取到 360 條,沒(méi)有實(shí)際意義。
  4.青波新榜
  如果你只是想看數據,你可以不花錢(qián)只看每日清單。如果你需要訪(fǎng)問(wèn)自己的系統,他們也提供了一個(gè)api接口 查看全部

  文章采集調用(1.用python爬取代理批量采集實(shí)現方法:anyproxy+js)
  微信公眾號文章爬取方法整理1.用python爬取
  php
  實(shí)現方法:通過(guò)微信提供的公眾號文章調用接口,實(shí)現抓取公眾號文章html的功能
  步驟:java
  1.需要安裝python selenium模塊包,使用selenium中的webdriver驅動(dòng)瀏覽器獲取cookies,達到登錄的效果;Python
  2.使用webdriver功能需要安裝對應瀏覽器的驅動(dòng)插件。我在這里使用谷歌瀏覽器進(jìn)行測試:
  谷歌瀏覽器版本是 52.0.2743.6 ;
  chromedriver版本為:V2.23
  注意:谷歌瀏覽器版本和chromedriver需要對應,否則啟動(dòng)時(shí)會(huì )報錯?!靖剑簊elenium的chromedriver和chrome版本映射表(更新為v2.30))】web
  3.微信公眾號登錄地址:chrome
  4.微信公眾號文章界面地址可以在微信公眾號后臺創(chuàng )建圖文信息,從超鏈接函數中獲?。簲祿?br />   5.搜索公眾號api
  6.獲取要爬取公眾號的fakeid瀏覽器
  7.選擇要爬取的公眾號,獲取文章接口地址微信
  8.文章列表翻頁(yè)和內容獲取
  2.AnyProxy 代理批量采集
  實(shí)現方式:anyproxy+js
  實(shí)現方式:anyproxy+java+webmagic
  3.FiddlerCore
  實(shí)現方式:抓包工具,Fiddler4
  經(jīng)過(guò)多個(gè)賬號的抓包分析,可以確認:
  _biz:這個(gè)14位的字符串是每一個(gè)公眾號的“id”,搜狗的微信平臺能夠得到
uin:與訪(fǎng)問(wèn)者有關(guān),微信號id
key:和所訪(fǎng)問(wèn)的公眾號有關(guān)
  步:
  1、編寫(xiě)按鈕向導腳本,在手機端自動(dòng)點(diǎn)擊公眾號文章的列表頁(yè)面,即“查看歷史消息”;
  2、使用fiddler代理劫持??手機訪(fǎng)問(wèn),將URL轉發(fā)到php編寫(xiě)的本地網(wǎng)頁(yè);
  3、將接收到的URL備份到php網(wǎng)頁(yè)上的數據庫中;
  4、使用python從數據庫中檢索URL,然后進(jìn)行正常爬取。
  在爬升過(guò)程中發(fā)現了一個(gè)問(wèn)題:
  如果只是想爬文章的內容,貌似沒(méi)有訪(fǎng)問(wèn)頻率限制,但是如果你想爬讀點(diǎn)贊數,達到一定頻率后,返回值會(huì )變成null,我設置的時(shí)間間隔為10秒,可以正常取到。在這個(gè)頻率下,一個(gè)小時(shí)只能取到 360 條,沒(méi)有實(shí)際意義。
  4.青波新榜
  如果你只是想看數據,你可以不花錢(qián)只看每日清單。如果你需要訪(fǎng)問(wèn)自己的系統,他們也提供了一個(gè)api接口

文章采集調用(設為“星標”,好文章不錯過(guò)!(組圖))

采集交流 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 170 次瀏覽 ? 2022-04-10 19:27 ? 來(lái)自相關(guān)話(huà)題

  文章采集調用(設為“星標”,好文章不錯過(guò)!(組圖))
  設置為“star”,所以文章不要錯過(guò)!
  
  1 服務(wù)跟蹤系統的意義
  
  1.1 快速定位請求失敗的原因
  
  在微服務(wù)架構下,有很多服務(wù)。如果上游請求失敗,要找出是哪個(gè)應用程序導致它是一場(chǎng)噩夢(mèng)!
  
  如果有系統,它可以跟蹤記錄用戶(hù)請求發(fā)起了哪些調用,處理了哪些服務(wù),并記錄了每次調用所涉及的服務(wù)的詳細信息。如果調用失敗,可以通過(guò)日志快速定位問(wèn)題!
  1.2 優(yōu)化系統瓶頸
  
  通過(guò)記錄調用經(jīng)過(guò)的每個(gè)環(huán)節的耗時(shí),可以快速定位整個(gè)系統的瓶頸點(diǎn)。比如你訪(fǎng)問(wèn)xxx網(wǎng)站的首頁(yè),發(fā)現速度很慢,可能是運營(yíng)商網(wǎng)絡(luò )延遲、網(wǎng)關(guān)系統異常、服務(wù)異常、緩存或者DB異常。通過(guò)服務(wù)跟蹤,可以從上帝視角看到整個(gè)系統的瓶頸點(diǎn),然后針對性的優(yōu)化。
  1.3 優(yōu)化鏈接調用
  
  分析調用經(jīng)過(guò)的路徑,評估是否合理,每個(gè)依賴(lài)是否必要,是否可以通過(guò)業(yè)務(wù)優(yōu)化減少服務(wù)依賴(lài)。
  一般情況下,服務(wù)部署在多個(gè)數據中心,實(shí)現異地容災。此時(shí)服務(wù)A經(jīng)常調用另一個(gè)數據中心的服務(wù)B,而不會(huì )調用同一個(gè)數據中心的服務(wù)B。
  跨數據中心的呼叫會(huì )根據距離有一定的網(wǎng)絡(luò )延遲,這對于某些業(yè)務(wù)來(lái)說(shuō)是無(wú)法接受的。通過(guò)分析調用鏈,可以識別和優(yōu)化跨數據中心的服務(wù)調用。
  1.4 生成網(wǎng)絡(luò )拓撲
  
  通過(guò)記錄的鏈路信息,可以生成系統的網(wǎng)絡(luò )調用拓撲圖,可以反映系統依賴(lài)哪些服務(wù),服務(wù)之間的調用關(guān)系是什么,一目了然。
  服務(wù)調用的詳細信息也可以標注在網(wǎng)絡(luò )拓撲圖上,也可以起到服務(wù)監控的作用。
  1.5 數據透傳
  
  業(yè)務(wù)中經(jīng)常有需求,期望從調用開(kāi)始就可以傳遞一些用戶(hù)數據,讓系統中的每個(gè)服務(wù)都能獲取到這些信息。比如一個(gè)業(yè)務(wù)要做一些A/B測試,想把A/B測試的切換邏輯一路向下通過(guò)服務(wù)跟蹤系統,經(jīng)過(guò)的每一層服務(wù)都可以得到切換值,從而可以統一A/B測試。.
  
  2 服務(wù)跟蹤系統原理
  
  服務(wù)跟蹤系統的鼻祖:Google 的論文 Dapper, a Large-Scale Distributed Systems Tracing Infrastructure 詳細解釋了服務(wù)跟蹤系統的實(shí)現原理。
  2.1 核心概念
  
  
  
  跟蹤標識
  
  全局唯一的 64 位整數,用于標識特定的請求 ID。
  它在 RPC 調用的網(wǎng)絡(luò )鏈路中不斷傳輸,將一個(gè)請求在系統中經(jīng)過(guò)的所有路徑串聯(lián)起來(lái)。
  
  跨度ID
  
  它用于標識一個(gè)RPC調用在分布式請求中的位置,以及區分系統中不同服務(wù)之間的調用順序。
  當用戶(hù)的請求進(jìn)入系統時(shí),在RPC調用網(wǎng)絡(luò )第一層A時(shí)spanId初始值為0,進(jìn)入下一層RPC調用B時(shí)spanId為0.1,并繼續進(jìn)入下一層RPC調用在C中,spanId為0.1.1,與B同層的RPC調用E的spanId為0.2,這樣某個(gè)RPC請求就可以通過(guò)spanId在系統中定位到調用中的位置,以及它的上下游依賴(lài)是誰(shuí)。這類(lèi)似于霍夫曼編碼。
  
  注解
  
  用于自定義業(yè)務(wù)的嵌入點(diǎn)數據??梢允菢I(yè)務(wù)感興趣并想上傳到后端的數據,比如一個(gè)請求的用戶(hù)UID。
  商家自定義一些自己感興趣的數據,除了上傳traceId、spanId等基本信息外,添加一些自己感興趣的信息。
  
  3 服務(wù)跟蹤系統的實(shí)施
  
  服務(wù)跟蹤系統可分為三層:
  3.1 個(gè)數據采集圖層
  
  在系統的不同模塊中嵌入點(diǎn),采集數據并上報給數據處理層進(jìn)行處理。
  那么如何掩埋數據呢?結合下圖來(lái)了解數據嵌入的過(guò)程。
  
  以紅框圈出的A調用B的過(guò)程為例,一個(gè)RPC請求可以分為四個(gè)階段。
  CS(Client Send)階段:客戶(hù)端發(fā)起請求并生成調用的上下文
  SR(Server Recieve)階段:服務(wù)器接收請求并生成上下文
  SS(Server Send)階段:服務(wù)器返回請求。在此階段,將報告服務(wù)器上下文數據。下圖顯示上報數據為:traceId=123456, spanId=0.1, appKey=B, method=B.method, start=103, duration=38
  CR(Client Recieve)階段:客戶(hù)端接收返回的結果。此階段將報告客戶(hù)端上下文數據。上報數據為:traceid=123456,spanId=0.1,appKey=A,method=B.method,start=103,duration=38。
  
  3.2 數據處理層
  
  按需計算data采集層上報的數據,然后存儲在地面上供查詢(xún)使用。
  據我所知,數據處理需求一般分為兩類(lèi),一類(lèi)是實(shí)時(shí)計算需求,一類(lèi)是離線(xiàn)計算需求。
  實(shí)時(shí)計算要求需要較高的計算效率。一般要求采集到的鏈路數據可以秒級聚合,實(shí)時(shí)查詢(xún)。但是,離線(xiàn)計算的需求并不需要那么高的計算效率。一般可以在小時(shí)級別完成鏈路數據的聚合計算,一般用于數據匯總統計。對于這兩類(lèi)不同的數據處理需求,所使用的計算方式和存儲也是不同的。
  3.3 數據表示層
  
  數據展示層的作用是將處理后的鏈接信息以圖形方式展示給用戶(hù)。
  主要使用以下兩個(gè)圖形:
  
  調用鏈接圖
  
  從這張圖中可以看出:
  在實(shí)際項目中,調用鏈路圖主要用于故障定位。例如,如果用戶(hù)調用失敗,可以通過(guò)調用鏈路圖查詢(xún)用戶(hù)調用經(jīng)過(guò)了哪些鏈路,以及調用失敗的層級。造成的。
  
  呼叫拓撲
  
  呼叫拓撲圖是全局視圖圖。在實(shí)際項目中,主要用于全局監控,以發(fā)現系統中的異常點(diǎn)并快速做出決策。比如某個(gè)服務(wù)突然出現異常,在調用鏈路拓撲圖中可以看出該服務(wù)的調用時(shí)間增加了,可以用紅色圖案標注,用于監控和告警。
  參考
  過(guò)去推薦
  廠(chǎng)家如何解決數值精度/舍入/溢出問(wèn)題
  大廠(chǎng)數據庫事務(wù)實(shí)踐——事務(wù)生效后能否正確回滾?
  在線(xiàn)問(wèn)題事跡(一)數據庫事務(wù)沒(méi)有生效? 查看全部

  文章采集調用(設為“星標”,好文章不錯過(guò)!(組圖))
  設置為“star”,所以文章不要錯過(guò)!
  
  1 服務(wù)跟蹤系統的意義
  
  1.1 快速定位請求失敗的原因
  
  在微服務(wù)架構下,有很多服務(wù)。如果上游請求失敗,要找出是哪個(gè)應用程序導致它是一場(chǎng)噩夢(mèng)!
  
  如果有系統,它可以跟蹤記錄用戶(hù)請求發(fā)起了哪些調用,處理了哪些服務(wù),并記錄了每次調用所涉及的服務(wù)的詳細信息。如果調用失敗,可以通過(guò)日志快速定位問(wèn)題!
  1.2 優(yōu)化系統瓶頸
  
  通過(guò)記錄調用經(jīng)過(guò)的每個(gè)環(huán)節的耗時(shí),可以快速定位整個(gè)系統的瓶頸點(diǎn)。比如你訪(fǎng)問(wèn)xxx網(wǎng)站的首頁(yè),發(fā)現速度很慢,可能是運營(yíng)商網(wǎng)絡(luò )延遲、網(wǎng)關(guān)系統異常、服務(wù)異常、緩存或者DB異常。通過(guò)服務(wù)跟蹤,可以從上帝視角看到整個(gè)系統的瓶頸點(diǎn),然后針對性的優(yōu)化。
  1.3 優(yōu)化鏈接調用
  
  分析調用經(jīng)過(guò)的路徑,評估是否合理,每個(gè)依賴(lài)是否必要,是否可以通過(guò)業(yè)務(wù)優(yōu)化減少服務(wù)依賴(lài)。
  一般情況下,服務(wù)部署在多個(gè)數據中心,實(shí)現異地容災。此時(shí)服務(wù)A經(jīng)常調用另一個(gè)數據中心的服務(wù)B,而不會(huì )調用同一個(gè)數據中心的服務(wù)B。
  跨數據中心的呼叫會(huì )根據距離有一定的網(wǎng)絡(luò )延遲,這對于某些業(yè)務(wù)來(lái)說(shuō)是無(wú)法接受的。通過(guò)分析調用鏈,可以識別和優(yōu)化跨數據中心的服務(wù)調用。
  1.4 生成網(wǎng)絡(luò )拓撲
  
  通過(guò)記錄的鏈路信息,可以生成系統的網(wǎng)絡(luò )調用拓撲圖,可以反映系統依賴(lài)哪些服務(wù),服務(wù)之間的調用關(guān)系是什么,一目了然。
  服務(wù)調用的詳細信息也可以標注在網(wǎng)絡(luò )拓撲圖上,也可以起到服務(wù)監控的作用。
  1.5 數據透傳
  
  業(yè)務(wù)中經(jīng)常有需求,期望從調用開(kāi)始就可以傳遞一些用戶(hù)數據,讓系統中的每個(gè)服務(wù)都能獲取到這些信息。比如一個(gè)業(yè)務(wù)要做一些A/B測試,想把A/B測試的切換邏輯一路向下通過(guò)服務(wù)跟蹤系統,經(jīng)過(guò)的每一層服務(wù)都可以得到切換值,從而可以統一A/B測試。.
  
  2 服務(wù)跟蹤系統原理
  
  服務(wù)跟蹤系統的鼻祖:Google 的論文 Dapper, a Large-Scale Distributed Systems Tracing Infrastructure 詳細解釋了服務(wù)跟蹤系統的實(shí)現原理。
  2.1 核心概念
  
  
  
  跟蹤標識
  
  全局唯一的 64 位整數,用于標識特定的請求 ID。
  它在 RPC 調用的網(wǎng)絡(luò )鏈路中不斷傳輸,將一個(gè)請求在系統中經(jīng)過(guò)的所有路徑串聯(lián)起來(lái)。
  
  跨度ID
  
  它用于標識一個(gè)RPC調用在分布式請求中的位置,以及區分系統中不同服務(wù)之間的調用順序。
  當用戶(hù)的請求進(jìn)入系統時(shí),在RPC調用網(wǎng)絡(luò )第一層A時(shí)spanId初始值為0,進(jìn)入下一層RPC調用B時(shí)spanId為0.1,并繼續進(jìn)入下一層RPC調用在C中,spanId為0.1.1,與B同層的RPC調用E的spanId為0.2,這樣某個(gè)RPC請求就可以通過(guò)spanId在系統中定位到調用中的位置,以及它的上下游依賴(lài)是誰(shuí)。這類(lèi)似于霍夫曼編碼。
  
  注解
  
  用于自定義業(yè)務(wù)的嵌入點(diǎn)數據??梢允菢I(yè)務(wù)感興趣并想上傳到后端的數據,比如一個(gè)請求的用戶(hù)UID。
  商家自定義一些自己感興趣的數據,除了上傳traceId、spanId等基本信息外,添加一些自己感興趣的信息。
  
  3 服務(wù)跟蹤系統的實(shí)施
  
  服務(wù)跟蹤系統可分為三層:
  3.1 個(gè)數據采集圖層
  
  在系統的不同模塊中嵌入點(diǎn),采集數據并上報給數據處理層進(jìn)行處理。
  那么如何掩埋數據呢?結合下圖來(lái)了解數據嵌入的過(guò)程。
  
  以紅框圈出的A調用B的過(guò)程為例,一個(gè)RPC請求可以分為四個(gè)階段。
  CS(Client Send)階段:客戶(hù)端發(fā)起請求并生成調用的上下文
  SR(Server Recieve)階段:服務(wù)器接收請求并生成上下文
  SS(Server Send)階段:服務(wù)器返回請求。在此階段,將報告服務(wù)器上下文數據。下圖顯示上報數據為:traceId=123456, spanId=0.1, appKey=B, method=B.method, start=103, duration=38
  CR(Client Recieve)階段:客戶(hù)端接收返回的結果。此階段將報告客戶(hù)端上下文數據。上報數據為:traceid=123456,spanId=0.1,appKey=A,method=B.method,start=103,duration=38。
  
  3.2 數據處理層
  
  按需計算data采集層上報的數據,然后存儲在地面上供查詢(xún)使用。
  據我所知,數據處理需求一般分為兩類(lèi),一類(lèi)是實(shí)時(shí)計算需求,一類(lèi)是離線(xiàn)計算需求。
  實(shí)時(shí)計算要求需要較高的計算效率。一般要求采集到的鏈路數據可以秒級聚合,實(shí)時(shí)查詢(xún)。但是,離線(xiàn)計算的需求并不需要那么高的計算效率。一般可以在小時(shí)級別完成鏈路數據的聚合計算,一般用于數據匯總統計。對于這兩類(lèi)不同的數據處理需求,所使用的計算方式和存儲也是不同的。
  3.3 數據表示層
  
  數據展示層的作用是將處理后的鏈接信息以圖形方式展示給用戶(hù)。
  主要使用以下兩個(gè)圖形:
  
  調用鏈接圖
  
  從這張圖中可以看出:
  在實(shí)際項目中,調用鏈路圖主要用于故障定位。例如,如果用戶(hù)調用失敗,可以通過(guò)調用鏈路圖查詢(xún)用戶(hù)調用經(jīng)過(guò)了哪些鏈路,以及調用失敗的層級。造成的。
  
  呼叫拓撲
  
  呼叫拓撲圖是全局視圖圖。在實(shí)際項目中,主要用于全局監控,以發(fā)現系統中的異常點(diǎn)并快速做出決策。比如某個(gè)服務(wù)突然出現異常,在調用鏈路拓撲圖中可以看出該服務(wù)的調用時(shí)間增加了,可以用紅色圖案標注,用于監控和告警。
  參考
  過(guò)去推薦
  廠(chǎng)家如何解決數值精度/舍入/溢出問(wèn)題
  大廠(chǎng)數據庫事務(wù)實(shí)踐——事務(wù)生效后能否正確回滾?
  在線(xiàn)問(wèn)題事跡(一)數據庫事務(wù)沒(méi)有生效?

文章采集調用(這部分資料大部分都是都是:如何編程經(jīng)驗總結了一下,效果并不好)

采集交流 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 124 次瀏覽 ? 2022-04-10 19:23 ? 來(lái)自相關(guān)話(huà)題

  文章采集調用(這部分資料大部分都是都是:如何編程經(jīng)驗總結了一下,效果并不好)
  主機:ubuntu 10.10 開(kāi)發(fā)板:Tiny6410 交叉編譯工具鏈:atm-linux-gcc 4.3.2qt 版本:QtEmbedded-4.5.2 - arm 最近在Tiny6410上編程攝像頭的時(shí)候,從網(wǎng)上找了很多資料學(xué)習,但是效果不好,因為網(wǎng)上大部分資料都不是很詳細,如果有V4L2編程經(jīng)驗的話(huà). 都差不多,不過(guò)對于我這種剛入門(mén)的人來(lái)說(shuō)太麻煩了。這部分信息大部分是:1、詳細介紹如何編程V4L2,但沒(méi)有提供源代碼示例。2、提供了源代碼,但注釋很少。難以閱讀。于是總結了一篇文章文章,總結了編程心得,這些例子可以在Tiny6410開(kāi)發(fā)板上運行,也可以直接在ubuntu 10.10上運行,可以使用的攝像頭有OV9650、USB接口OV301等,只需對源碼稍作改動(dòng)即可。關(guān)于 videodevice 是我在網(wǎng)上找到的一條資料。我覺(jué)得他寫(xiě)的很好,所以也收錄在里面供大家參考。如果您有任何問(wèn)題,請與我聯(lián)系。我的郵箱是:我要注意:我上次上傳的代碼不是我上次修改的代碼,雖然沒(méi)有問(wèn)題,但是我還是覺(jué)得再上傳一次就好了,就是不知道怎么改刪除之前上傳的代碼,只能重新發(fā)送。關(guān)于 videodevice 是我在網(wǎng)上找到的一條資料。我覺(jué)得他寫(xiě)的很好,所以也收錄在里面供大家參考。如果您有任何問(wèn)題,請與我聯(lián)系。我的郵箱是:我要注意:我上次上傳的代碼不是我上次修改的代碼,雖然沒(méi)有問(wèn)題,但是我還是覺(jué)得再上傳一次就好了,就是不知道怎么改刪除之前上傳的代碼,只能重新發(fā)送。關(guān)于 videodevice 是我在網(wǎng)上找到的一條資料。我覺(jué)得他寫(xiě)的很好,所以也收錄在里面供大家參考。如果您有任何問(wèn)題,請與我聯(lián)系。我的郵箱是:我要注意:我上次上傳的代碼不是我上次修改的代碼,雖然沒(méi)有問(wèn)題,但是我還是覺(jué)得再上傳一次就好了,就是不知道怎么改刪除之前上傳的代碼,只能重新發(fā)送。 查看全部

  文章采集調用(這部分資料大部分都是都是:如何編程經(jīng)驗總結了一下,效果并不好)
  主機:ubuntu 10.10 開(kāi)發(fā)板:Tiny6410 交叉編譯工具鏈:atm-linux-gcc 4.3.2qt 版本:QtEmbedded-4.5.2 - arm 最近在Tiny6410上編程攝像頭的時(shí)候,從網(wǎng)上找了很多資料學(xué)習,但是效果不好,因為網(wǎng)上大部分資料都不是很詳細,如果有V4L2編程經(jīng)驗的話(huà). 都差不多,不過(guò)對于我這種剛入門(mén)的人來(lái)說(shuō)太麻煩了。這部分信息大部分是:1、詳細介紹如何編程V4L2,但沒(méi)有提供源代碼示例。2、提供了源代碼,但注釋很少。難以閱讀。于是總結了一篇文章文章,總結了編程心得,這些例子可以在Tiny6410開(kāi)發(fā)板上運行,也可以直接在ubuntu 10.10上運行,可以使用的攝像頭有OV9650、USB接口OV301等,只需對源碼稍作改動(dòng)即可。關(guān)于 videodevice 是我在網(wǎng)上找到的一條資料。我覺(jué)得他寫(xiě)的很好,所以也收錄在里面供大家參考。如果您有任何問(wèn)題,請與我聯(lián)系。我的郵箱是:我要注意:我上次上傳的代碼不是我上次修改的代碼,雖然沒(méi)有問(wèn)題,但是我還是覺(jué)得再上傳一次就好了,就是不知道怎么改刪除之前上傳的代碼,只能重新發(fā)送。關(guān)于 videodevice 是我在網(wǎng)上找到的一條資料。我覺(jué)得他寫(xiě)的很好,所以也收錄在里面供大家參考。如果您有任何問(wèn)題,請與我聯(lián)系。我的郵箱是:我要注意:我上次上傳的代碼不是我上次修改的代碼,雖然沒(méi)有問(wèn)題,但是我還是覺(jué)得再上傳一次就好了,就是不知道怎么改刪除之前上傳的代碼,只能重新發(fā)送。關(guān)于 videodevice 是我在網(wǎng)上找到的一條資料。我覺(jué)得他寫(xiě)的很好,所以也收錄在里面供大家參考。如果您有任何問(wèn)題,請與我聯(lián)系。我的郵箱是:我要注意:我上次上傳的代碼不是我上次修改的代碼,雖然沒(méi)有問(wèn)題,但是我還是覺(jué)得再上傳一次就好了,就是不知道怎么改刪除之前上傳的代碼,只能重新發(fā)送。

文章采集調用(文章采集調用服務(wù)的xml格式的接口,無(wú)需restfulapi)

采集交流 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 140 次瀏覽 ? 2022-04-09 23:03 ? 來(lái)自相關(guān)話(huà)題

  文章采集調用(文章采集調用服務(wù)的xml格式的接口,無(wú)需restfulapi)
  文章采集調用服務(wù)的xml格式的接口,無(wú)需restfulapi,一切交給c++,或者用epoll、select等異步網(wǎng)絡(luò )調用即可.現有文章內容抓取及商品xml接口通過(guò)開(kāi)發(fā)一個(gè)簡(jiǎn)單的爬蟲(chóng),能夠最大限度的節省url請求和返回的訪(fǎng)問(wèn)成本。本小節以杭州某地的某線(xiàn)索網(wǎng)站為例講解如何開(kāi)發(fā)一個(gè)簡(jiǎn)單的爬蟲(chóng)。由于杭州市的所有信息全部都在這一小塊地圖上,爬蟲(chóng)必須讀取這些數據,可以很快速的進(jìn)行數據采集。
  爬蟲(chóng)的實(shí)現要先針對這個(gè)網(wǎng)站的數據進(jìn)行分析,得到每個(gè)url對應的vi信息即當前頁(yè)內容,以及當前頁(yè)內容對應的url之前的所有歷史價(jià)格數據。得到每個(gè)url對應的vi信息即當前頁(yè)內容對應的url之前的所有歷史價(jià)格數據爬蟲(chóng)的代碼是通過(guò)兩個(gè)c++的源文件完成。以杭州市某的某線(xiàn)索網(wǎng)站為例(杭州市的網(wǎng)址則在此網(wǎng)址后面存放),可以理解爬蟲(chóng)只需要通過(guò)url完成第一步所有的任務(wù),然后解析所有url的內容返回給服務(wù)端即可。
<p>有了數據,接下來(lái)就是網(wǎng)站的代碼實(shí)現,以及如何抓取數據了。爬蟲(chóng)的代碼:#include#include#includeusingnamespacestd;constintmaxpage=10;//一頁(yè)的長(cháng)度#includeintmain(){void*path;stringfilename;charcontent[]="/";charcontent[]="\n";string[]arrays;present_content(path);filename=0;file_tindex;charlines[]=path.size();char[]next;for(index=0;index 查看全部

  文章采集調用(文章采集調用服務(wù)的xml格式的接口,無(wú)需restfulapi)
  文章采集調用服務(wù)的xml格式的接口,無(wú)需restfulapi,一切交給c++,或者用epoll、select等異步網(wǎng)絡(luò )調用即可.現有文章內容抓取及商品xml接口通過(guò)開(kāi)發(fā)一個(gè)簡(jiǎn)單的爬蟲(chóng),能夠最大限度的節省url請求和返回的訪(fǎng)問(wèn)成本。本小節以杭州某地的某線(xiàn)索網(wǎng)站為例講解如何開(kāi)發(fā)一個(gè)簡(jiǎn)單的爬蟲(chóng)。由于杭州市的所有信息全部都在這一小塊地圖上,爬蟲(chóng)必須讀取這些數據,可以很快速的進(jìn)行數據采集。
  爬蟲(chóng)的實(shí)現要先針對這個(gè)網(wǎng)站的數據進(jìn)行分析,得到每個(gè)url對應的vi信息即當前頁(yè)內容,以及當前頁(yè)內容對應的url之前的所有歷史價(jià)格數據。得到每個(gè)url對應的vi信息即當前頁(yè)內容對應的url之前的所有歷史價(jià)格數據爬蟲(chóng)的代碼是通過(guò)兩個(gè)c++的源文件完成。以杭州市某的某線(xiàn)索網(wǎng)站為例(杭州市的網(wǎng)址則在此網(wǎng)址后面存放),可以理解爬蟲(chóng)只需要通過(guò)url完成第一步所有的任務(wù),然后解析所有url的內容返回給服務(wù)端即可。
<p>有了數據,接下來(lái)就是網(wǎng)站的代碼實(shí)現,以及如何抓取數據了。爬蟲(chóng)的代碼:#include#include#includeusingnamespacestd;constintmaxpage=10;//一頁(yè)的長(cháng)度#includeintmain(){void*path;stringfilename;charcontent[]="/";charcontent[]="\n";string[]arrays;present_content(path);filename=0;file_tindex;charlines[]=path.size();char[]next;for(index=0;index

文章采集調用(通過(guò)SpringBootActuatorWebAPI監控應用狀態(tài)actuatorWeb)

采集交流 ? 優(yōu)采云 發(fā)表了文章 ? 0 個(gè)評論 ? 140 次瀏覽 ? 2022-04-09 18:42 ? 來(lái)自相關(guān)話(huà)題

  文章采集調用(通過(guò)SpringBootActuatorWebAPI監控應用狀態(tài)actuatorWeb)
  環(huán)境需求案例:通過(guò) Spring Boot Actuator Web API 監控應用狀態(tài)
  執行器提供了一個(gè)健康端點(diǎn),用于獲取有關(guān)應用程序健康的詳細信息。
  官方文檔地址:#health
  URL地址是:
  /執行器/健康
  返回結果(JSON數據格式):
  {
"status": "UP",
"components": {
"custom": {
"status": "UP",
"details": {
"app": "Alive and Kicking",
"error": "Nothing! I&#39;m good."
}
},
"diskSpace": {
"status": "UP",
"details": {
"total": 52776349696,
"free": 43368595456,
"threshold": 10485760
}
},
"ping": {
"status": "UP"
}
}
}
  配置監控項
  建議使用Zabbix的主監控項+從屬監控項(相關(guān)項)實(shí)現采集一次多個(gè)數據調用,減少API調用次數。
  第一步:創(chuàng )建主監控項
  創(chuàng )建監控項,修改如下配置:
  如果API接口需要認證,可以設置HTTP認證。使用宏變量支持用戶(hù)名和密碼。
  
  
  配置完成后,點(diǎn)擊下方測試,點(diǎn)擊獲取值并測試,查看是否可以正確獲取數據。
  
  第二步:創(chuàng )建依賴(lài)監控項(相關(guān)項)
  假設您需要監控應用程序的狀態(tài)和磁盤(pán)的剩余空間。
  指標 1:監控應用程序狀態(tài)
  JSONPath語(yǔ)法說(shuō)明參考官方文檔:
  創(chuàng )建監控項,修改如下配置:
  
  將步驟添加到“進(jìn)程”選項卡:
  
  點(diǎn)擊下面的Test all steps來(lái)驗證配置,在value中填入主監控項test獲取的數據,點(diǎn)擊Test查看是否可以正確獲取數據。
  
  指標 2:監控磁盤(pán)剩余空間
  創(chuàng )建監控項,修改如下配置:
  
  將步驟添加到“進(jìn)程”選項卡:
  
  點(diǎn)擊下面的Test all steps來(lái)驗證配置,在value中填入主監控項test獲取的數據,點(diǎn)擊Test查看是否可以正確獲取數據。
  
  檢查最新數據是否正常采集
  注:依賴(lài)監控項(相關(guān)項)的數據更新周期由主監控項設置的更新周期決定
  
  至此,監控項的配置已經(jīng)完成,接下來(lái)就可以根據實(shí)際情況配置相應的觸發(fā)器了。
  配置模板時(shí),可以將主監控項中的URL配置為宏宏變量,例如:{$HOST}:{$PORT}/actuator/health,這樣可以在鏈接時(shí)為不同的主機設置宏變量模板(用戶(hù)名和密碼也可以這樣配置)。 查看全部

  文章采集調用(通過(guò)SpringBootActuatorWebAPI監控應用狀態(tài)actuatorWeb)
  環(huán)境需求案例:通過(guò) Spring Boot Actuator Web API 監控應用狀態(tài)
  執行器提供了一個(gè)健康端點(diǎn),用于獲取有關(guān)應用程序健康的詳細信息。
  官方文檔地址:#health
  URL地址是:
  /執行器/健康
  返回結果(JSON數據格式):
  {
"status": "UP",
"components": {
"custom": {
"status": "UP",
"details": {
"app": "Alive and Kicking",
"error": "Nothing! I&#39;m good."
}
},
"diskSpace": {
"status": "UP",
"details": {
"total": 52776349696,
"free": 43368595456,
"threshold": 10485760
}
},
"ping": {
"status": "UP"
}
}
}
  配置監控項
  建議使用Zabbix的主監控項+從屬監控項(相關(guān)項)實(shí)現采集一次多個(gè)數據調用,減少API調用次數。
  第一步:創(chuàng )建主監控項
  創(chuàng )建監控項,修改如下配置:
  如果API接口需要認證,可以設置HTTP認證。使用宏變量支持用戶(hù)名和密碼。
  
  
  配置完成后,點(diǎn)擊下方測試,點(diǎn)擊獲取值并測試,查看是否可以正確獲取數據。
  
  第二步:創(chuàng )建依賴(lài)監控項(相關(guān)項)
  假設您需要監控應用程序的狀態(tài)和磁盤(pán)的剩余空間。
  指標 1:監控應用程序狀態(tài)
  JSONPath語(yǔ)法說(shuō)明參考官方文檔:
  創(chuàng )建監控項,修改如下配置:
  
  將步驟添加到“進(jìn)程”選項卡:
  
  點(diǎn)擊下面的Test all steps來(lái)驗證配置,在value中填入主監控項test獲取的數據,點(diǎn)擊Test查看是否可以正確獲取數據。
  
  指標 2:監控磁盤(pán)剩余空間
  創(chuàng )建監控項,修改如下配置:
  
  將步驟添加到“進(jìn)程”選項卡:
  
  點(diǎn)擊下面的Test all steps來(lái)驗證配置,在value中填入主監控項test獲取的數據,點(diǎn)擊Test查看是否可以正確獲取數據。
  
  檢查最新數據是否正常采集
  注:依賴(lài)監控項(相關(guān)項)的數據更新周期由主監控項設置的更新周期決定
  
  至此,監控項的配置已經(jīng)完成,接下來(lái)就可以根據實(shí)際情況配置相應的觸發(fā)器了。
  配置模板時(shí),可以將主監控項中的URL配置為宏宏變量,例如:{$HOST}:{$PORT}/actuator/health,這樣可以在鏈接時(shí)為不同的主機設置宏變量模板(用戶(hù)名和密碼也可以這樣配置)。

官方客服QQ群

微信人工客服

QQ人工客服


線(xiàn)

亚洲国产精品无码久久大片,亚洲AV无码乱码麻豆精品国产,亚洲品质自拍网站,少妇伦子伦精品无码STYLES,国产精久久久久久久