精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

使用Shell構建多進程的CommandlineFu爬蟲

開發 后端
CommandlineFu 是一個記錄腳本片段的網站,每個片段都有對應的功能說明和對應的標簽。我想要做的就是嘗試用 shell 寫一個多進程的爬蟲把這些代碼片段記錄在一個 org 文件中。

[[259230]]

 CommandlineFu 是一個記錄腳本片段的網站,每個片段都有對應的功能說明和對應的標簽。我想要做的就是嘗試用 shell 寫一個多進程的爬蟲把這些代碼片段記錄在一個 org 文件中。

參數定義

這個腳本需要能夠通過 -n 參數指定并發的爬蟲數(默認為 CPU 核的數量),還要能通過 -f 指定保存的 org 文件路徑(默認輸出到 stdout)。

  1. #!/usr/bin/env bash
  2.  
  3. proc_num=$(nproc)
  4. store_file=/dev/stdout
  5. while getopts :n:f: OPT; do
  6. case $OPT in
  7. n|+n)
  8. proc_num="$OPTARG"
  9. ;;
  10. f|+f)
  11. store_file="$OPTARG"
  12. ;;
  13. *)
  14. echo "usage: ${0##*/} [+-n proc_num] [+-f org_file} [--]"
  15. exit 2
  16. esac
  17. done
  18. shift $(( OPTIND - 1 ))
  19. OPTIND=1

解析命令瀏覽頁面

我們需要一個進程從 CommandlineFu 的瀏覽列表中抽取各個腳本片段的 URL,這個進程將抽取出來的 URL 存放到一個隊列中,再由各個爬蟲進程從進程中讀取 URL 并從中抽取出對應的代碼片段、描述說明和標簽信息寫入 org 文件中。

這里就會遇到三個問題:

  1. 進程之間通訊的隊列如何實現
  2. 如何從頁面中抽取出 URL、代碼片段、描述說明、標簽等信息
  3. 多進程對同一文件進行讀寫時的亂序問題

實現進程之間的通訊隊列

這個問題比較好解決,我們可以通過一個命名管道來實現:

  1. queue=$(mktemp --dry-run)
  2. mkfifo ${queue}
  3. exec 99<>${queue}
  4. trap "rm ${queue} 2>/dev/null" EXIT

從頁面中抽取想要的信息

從頁面中提取元素內容主要有兩種方法:

  1. 對于簡單的 HTML 頁面,我們可以通過 sedgrepawk 等工具通過正則表達式匹配的方式來從 HTML 中抽取信息。
  2. 通過 html-xml-utils 工具集中的 hxselect 來根據 CSS 選擇器提取相關元素。

這里我們使用 html-xml-utils 工具來提取:

  1. function extract_views_from_browse_page()
  2. {
  3. if [[ $# -eq 0 ]];then
  4. local html=$(cat -)
  5. else
  6. local html="$*"
  7. fi
  8. echo ${html} |hxclean |hxselect -c -s "\n" "li.list-group-item > div:nth-child(1) > div:nth-child(1) > a:nth-child(1)::attr(href)"|sed 's@^@https://www.commandlinefu.com/@'
  9. }
  10.  
  11. function extract_nextpage_from_browse_page()
  12. {
  13. if [[ $# -eq 0 ]];then
  14. local html=$(cat -)
  15. else
  16. local html="$*"
  17. fi
  18. echo ${html} |hxclean |hxselect -s "\n" "li.list-group-item:nth-child(26) > a"|grep '>'|hxselect -c "::attr(href)"|sed 's@^@https://www.commandlinefu.com/@'
  19. }

這里需要注意的是:hxselect 對 HTML 解析時要求遵循嚴格的 XML 規范,因此在用 hxselect 解析之前需要先經過 hxclean 矯正。另外,為了防止 HTML 過大,超過參數列表長度,這里允許通過管道的形式將  HTML 內容傳入。

循環讀取下一頁的瀏覽頁面,不斷抽取代碼片段 URL 寫入隊列

這里要解決的是上面提到的第三個問題: 多進程對管道進行讀寫時如何保障不出現亂序? 為此,我們需要在寫入文件時對文件加鎖,然后在寫完文件后對文件解鎖,在 shell 中我們可以使用 flock 來對文件進行枷鎖。 關于 flock 的使用方法和注意事項,請參見另一篇博文 Linux shell flock 文件鎖的用法及注意事項

由于需要在 flock 子進程中使用函數 extract_views_from_browse_page,因此需要先導出該函數:

  1. export -f extract_views_from_browse_page

由于網絡問題,使用 curl 獲取內容可能失敗,需要重復獲取:

  1. function fetch()
  2. {
  3. local url="$1"
  4. while ! curl -L ${url} 2>/dev/null;do
  5. :
  6. done
  7. }

collector 用來從種子 URL 中抓取待爬的 URL,寫入管道文件中,寫操作期間管道文件同時作為鎖文件:

  1. function collector()
  2. {
  3. url="$*"
  4. while [[ -n ${url} ]];do
  5. echo "從$url中抽取"
  6. html=$(fetch "${url}")
  7. echo "${html}"|flock ${queue} -c "extract_views_from_browse_page >${queue}"
  8. url=$(echo "${html}"|extract_nextpage_from_browse_page)
  9. done
  10. # 讓后面解析代碼片段的爬蟲進程能夠正常退出,而不至于被阻塞.
  11. for ((i=0;i<${proc_num};i++))
  12. do
  13. echo >${queue}
  14. done
  15. }

這里要注意的是, 在找不到下一頁 URL 后,我們用一個 for 循環往隊列里寫入了 =proc_num= 個空行,這一步的目的是讓后面解析代碼片段的爬蟲進程能夠正常退出,而不至于被阻塞。

解析腳本片段頁面

我們需要從腳本片段的頁面中抽取標題、代碼片段、描述說明以及標簽信息,同時將這些內容按 org 模式的格式寫入存儲文件中。

  1. function view_page_handler()
  2. {
  3. local url="$1"
  4. local html="$(fetch "${url}")"
  5. # headline
  6. local headline="$(echo ${html} |hxclean |hxselect -c -s "\n" ".col-md-8 > h1:nth-child(1)")"
  7. # command
  8. local command="$(echo ${html} |hxclean |hxselect -c -s "\n" ".col-md-8 > div:nth-child(2) > span:nth-child(2)"|pandoc -f html -t org)"
  9. # description
  10. local description="$(echo ${html} |hxclean |hxselect -c -s "\n" ".col-md-8 > div.description"|pandoc -f html -t org)"
  11. # tags
  12. local tags="$(echo ${html} |hxclean |hxselect -c -s ":" ".functions > a")"
  13. if [[ -n "${tags}" ]];then
  14. tags=":${tags}"
  15. fi
  16. # build org content
  17. cat <<EOF |flock -x ${store_file} tee -a ${store_file}
  18. * ${headline} ${tags}
  19.  
  20. :PROPERTIES:
  21. :URL: ${url}
  22. :END:
  23.  
  24. ${description}
  25. #+begin_src shell
  26. ${command}
  27. #+end_src
  28.  
  29. EOF
  30. }

這里抽取信息的方法跟上面的類似,不過代碼片段和描述說明中可能有一些 HTML 代碼,因此通過 pandoc 將之轉換為 org 格式的內容。

注意***輸出 org 模式的格式并寫入存儲文件中的代碼不要寫成下面這樣:

  1. flock -x ${store_file} cat <<EOF >${store_file}
  2. * ${headline}\t\t ${tags}
  3. ${description}
  4. #+begin_src shell
  5. ${command}
  6. #+end_src
  7. EOF

它的意思是使用 flock 對 cat 命令進行加鎖,再把 flock 整個命令的結果通過重定向輸出到存儲文件中,而重定向輸出的這個過程是沒有加鎖的。

spider 從管道文件中讀取待抓取的 URL,然后實施真正的抓取動作。

  1. function spider()
  2. {
  3. while :
  4. do
  5. if ! url=$(flock ${queue} -c 'read -t 1 -u 99 url && echo $url')
  6. then
  7. sleep 1
  8. continue
  9. fi
  10.  
  11. if [[ -z "$url" ]];then
  12. break
  13. fi
  14. view_page_handler ${url}
  15. done
  16. }

這里要注意的是,為了防止發生死鎖,從管道中讀取 URL 時設置了超時,當出現超時就意味著生產進程趕不上消費進程的消費速度,因此消費進程休眠一秒后再次檢查隊列中的 URL。

組合起來

  1. collector "https://www.commandlinefu.com/commands/browse" &
  2.  
  3. for ((i=0;i<${proc_num};i++))
  4. do
  5. spider &
  6. done
  7. wait

抓取其他網站

通過重新定義 extract_views_from_browse_pageextract_nextpage_from-browse_pageview_page_handler 這幾個函數, 以及提供一個新的種子 URL,我們可以很容易將其改造成抓取其他網站的多進程爬蟲。

例如通過下面這段代碼,就可以用來爬取 xkcd 上的漫畫:

  1. function extract_views_from_browse_page()
  2. {
  3. if [[ $# -eq 0 ]];then
  4. local html=$(cat -)
  5. else
  6. local html="$*"
  7. fi
  8. max=$(echo "${html}"|hxclean |hxselect -c -s "\n" "#middleContainer"|grep "Permanent link to this comic" |awk -F "/" '{print $4}')
  9. seq 1 ${max}|sed 's@^@https://xkcd.com/@'
  10. }
  11.  
  12. function extract_nextpage_from_browse_page()
  13. {
  14. echo ""
  15. }
  16.  
  17. function view_page_handler()
  18. {
  19. local url="$1"
  20. local html="$(fetch "${url}/")"
  21. local image="https:$(echo ${html} |hxclean |hxselect -c -s "\n" "#comic > img:nth-child(1)::attr(src)")"
  22. echo ${image}
  23. wget ${image}
  24. }
  25.  
  26. collector "https://xkcd.com/" &
責任編輯:龐桂玉 來源: Linux中國
相關推薦

2021-02-25 11:19:37

谷歌Android開發者

2024-03-08 12:17:39

網絡爬蟲Python開發

2017-06-30 10:12:46

Python多進程

2020-11-18 09:06:04

Python

2016-02-26 15:28:45

CasperJSWeb爬蟲

2009-04-21 09:12:45

Java多進程運行

2024-08-26 08:39:26

PHP孤兒進程僵尸進程

2019-02-26 11:15:25

進程多線程多進程

2010-07-15 12:51:17

Perl多進程

2017-04-25 15:20:11

Python進程mpi4py

2013-01-30 15:07:59

Shell

2022-04-19 20:39:03

協程多進程

2010-07-15 13:13:21

Perl多進程

2021-06-16 07:21:39

AndroidAndroid系統多進程通訊

2023-12-13 09:56:13

?多進程多線程協程

2012-08-08 09:32:26

C++多進程并發框架

2021-10-12 09:52:30

Webpack 前端多進程打包

2024-03-29 06:44:55

Python多進程模塊工具

2016-01-11 10:29:36

Docker容器容器技術

2022-07-11 10:23:42

云原生Python多核CPU
點贊
收藏

51CTO技術棧公眾號

国产成人综合精品在线| 日韩av中文字幕在线免费观看| 欧美精品激情blacked18| 性一交一黄一片| 激情aⅴ欧美一区二区欲海潮| 久久精品人人爽人人爽| 国产日韩精品电影| 日本网站免费观看| 精品日韩在线| 精品国产一区二区三区久久久蜜月| 黄色一级视频片| 在线观看av的网站| www.欧美色图| 91九色单男在线观看| 国产无码精品一区二区| 精品在线播放| 欧美sm极限捆绑bd| 一区二区三区网址| 日韩精品系列| 极品少妇xxxx偷拍精品少妇| 97久久国产精品| 26uuu成人网| 免费电影一区二区三区| 欧美成人一区二区三区在线观看| aaa毛片在线观看| 中文字幕伦理免费在线视频| 日本一区二区三区dvd视频在线| 成人午夜电影免费在线观看| 中文字幕第一页在线播放| 狠狠做六月爱婷婷综合aⅴ| 欧美成人性福生活免费看| 天天爽天天爽夜夜爽| 蜜桃成人在线视频| 岛国精品在线观看| 亚洲一区中文字幕| 在线免费看av片| 久久婷婷丁香| 亚洲欧美视频在线| 日本wwwwwww| v片在线观看| 久久久精品人体av艺术| 久久国产精品99久久久久久丝袜| 久久艹免费视频| 中文字幕免费精品| 色狠狠久久aa北条麻妃 | 91片黄在线观看| 91偷拍精品一区二区三区| 侵犯稚嫩小箩莉h文系列小说| 国产精品欧美三级在线观看| 精品一区二区三区三区| 日本一区二区在线免费观看| 白白在线精品| 精品福利av导航| 特级特黄刘亦菲aaa级| 国产专区精品| 日韩视频一区在线观看| 午夜激情影院在线观看| 91视频成人| 69久久夜色精品国产69蝌蚪网| 亚洲视频第二页| 91精品国产自产观看在线| 欧美猛男超大videosgay| 国产三级精品三级在线| 97精品资源在线观看| 69精品人人人人| 一级全黄裸体片| 久久国产精品色av免费看| 亚洲精品国产福利| 亚洲精品视频久久久| 精品久久久亚洲| 中文字幕欧美日韩va免费视频| 中文字幕在线观看二区| 欧美激情视频一区二区三区在线播放| 欧美人与性动交a欧美精品| 久久久精品人妻一区二区三区四| 欧美一区 二区| 日韩大片在线观看视频| 亚洲国产av一区| 91一区二区| 欧美高跟鞋交xxxxxhd| 国产精品成人久久| 石原莉奈在线亚洲三区| 国产精品主播视频| 肥臀熟女一区二区三区| 久久婷婷久久一区二区三区| 亚洲一区二区精品在线| 青青草视频在线免费直播| 精品日韩视频在线观看| 99热这里只有精品在线播放| 国产精品一区二区三区四区在线观看| 日韩一区二区中文字幕| 欧美性xxxx图片| 香蕉免费一区二区三区在线观看| 日本道在线观看一区二区| 久久久久免费精品| 国产电影一区| 亚洲精品综合精品自拍| 五月天色婷婷丁香| 日韩香蕉视频| 91精品综合久久久久久五月天| 日本高清视频www| 国产精品久久久久久久第一福利| 丁香婷婷综合激情| 国内精品久久久久久野外| 亚洲一区二区三区四区在线 | 精品日韩av一区二区| 久久丫精品国产亚洲av不卡| 91精品国产麻豆国产在线观看 | 黄色污在线观看| 久久中文字幕av一区二区不卡| 国内外成人免费激情在线视频网站 | 成人精品一区二区三区电影黑人| 欧美 日韩 国产 精品| 国产精品区一区二区三区| 成人免费播放器| 91国产一区| 国产一区二区三区在线观看网站| 国产精品第七页| 99国产**精品****| 欧美综合激情网| 午夜精品无码一区二区三区| 国产精品激情偷乱一区二区∴| 亚洲熟妇国产熟妇肥婆| 亚洲成av人片在线观看www| 中文字幕亚洲情99在线| 51国产偷自视频区视频| 成人h版在线观看| 综合久久国产| 国产精品久久久久久妇女| 亚洲国产欧美一区| 精品少妇theporn| 九九国产精品视频| 亚洲资源在线网| 日韩电影网站| 亚洲人在线视频| 日韩精品久久久久久久| 风间由美性色一区二区三区| 亚洲最大免费| 99精品在免费线偷拍| 亚洲人成网在线播放| 亚洲日本视频在线观看| 成人av影院在线| 韩日视频在线观看| 给我免费播放日韩视频| zzjj国产精品一区二区| 亚洲一卡二卡在线观看| 国产精品欧美综合在线| 中文字幕网av| 色男人天堂综合再现| 国产精品羞羞答答| 精品国产99久久久久久| 在线不卡一区二区| 黄色录像免费观看| 国产麻豆精品theporn| 国产精品视频500部| 欧美3p视频在线观看| 欧美性猛交xxxx乱大交极品| 免费的av网站| 毛片一区二区| 午夜精品短视频| 国产第一亚洲| 欧美大胆在线视频| 俄罗斯嫩小性bbwbbw| 午夜亚洲国产au精品一区二区| 国模无码视频一区| 亚洲欧美日韩视频二区| 欧美一区二区福利| 777午夜精品电影免费看| 最近2019中文字幕第三页视频| 岳乳丰满一区二区三区| 亚洲欧美日韩一区| 中文字幕天堂av| 久久久久久久欧美精品| 夜夜爽99久久国产综合精品女不卡 | 国产亚洲亚洲| 三级三级久久三级久久18| 日日夜夜亚洲| 亚洲精品国产品国语在线| 久久99精品波多结衣一区| 久久精品人人做| 亚洲天堂国产视频| 亚洲性视频h| 欧洲一区二区日韩在线视频观看免费 | 午夜免费福利网站| 国产亚洲精品v| 亚洲精品一品区二品区三品区| 国产一区二区三区国产精品| 2019日本中文字幕| 91在线播放网站| 欧美tickling网站挠脚心| 黄色av网站免费| 亚洲精品国产精品乱码不99| theav精尽人亡av| 久久精品国产第一区二区三区| 国产欧美久久久久| 欧美日韩国产高清电影| 国产精品自拍首页| 黄色精品视频| 亚洲激情视频网| 国产在线观看第一页| 亚洲欧美另类图片小说| 成人免费网站黄| 国产 日韩 欧美大片| 老司机午夜av| 精品白丝av| 中文字幕一区二区三区四区五区六区| 51亚洲精品| 国产精品一区av| 在线观看涩涩| 九九热r在线视频精品| eeuss影院在线播放| 亚洲国产另类久久精品 | 中文字幕这里只有精品| 欧美成人性色生活仑片| jizz在线观看视频| 国产视频久久久久| www.久久伊人| 欧美精品免费视频| 中文字幕精品无| 久久综合狠狠综合久久综合88| 免费精品99久久国产综合精品应用| 9国产精品视频| 国内自拍中文字幕| 国产精品黑丝在线播放| 色爱区成人综合网| 国产欧美一区二区精品久久久| 黑人另类av| 91综合精品国产丝袜长腿久久| 国产中文字幕91| 日韩成人亚洲| 日韩美女毛茸茸| 欧美aaaaa性bbbbb小妇| 欧美激情亚洲激情| 亚洲区欧洲区| 欧美人成在线视频| 羞羞污视频在线观看| 久热精品视频在线免费观看| 欧美黄色激情| 日韩网站免费观看高清| jizz日韩| 日韩专区在线观看| 在线观看黄色av| 色偷偷偷综合中文字幕;dd| 国模吧精品人体gogo| 亚洲日韩欧美视频| 成在在线免费视频| 国产一区二区三区在线看 | 精品午夜电影| 国产精品久久一区二区三区| 中文字幕av一区二区三区四区| 亚洲一区二区三区在线视频 | 蜜臀av一区二区| 亚洲一级片网站| 久久草av在线| 国产男女无遮挡猛进猛出| 国产精品一区二区在线播放| 黄页网站在线看| 不卡高清视频专区| 泷泽萝拉在线播放| 国产欧美日韩卡一| 熟女av一区二区| 亚洲国产综合色| 日韩av在线播| 日本二三区不卡| 91国内精品久久久| 日韩一区二区三区观看| 高h放荡受浪受bl| 日韩国产中文字幕| www 日韩| 色在人av网站天堂精品| 黄色在线免费观看网站| 国产suv精品一区二区三区88区| 成人18视频在线观看| 亚洲永久免费观看| 欧美18xxxx| 亚洲第一导航| 欧美三级午夜理伦三级中文幕| av免费观看网| 蜜桃av噜噜一区| 2018国产精品| 久久九九影视网| 成人免费精品动漫网站| 亚洲r级在线视频| 亚洲 欧美 日韩 在线| 欧美疯狂性受xxxxx喷水图片| 亚洲国产精品一| 国产香蕉97碰碰久久人人| free性欧美hd另类精品| 1769国内精品视频在线播放| 欧美黄色网络| 久久精品午夜一区二区福利| 久久国产电影| 欧美一级在线看| 久久精品国产一区二区三区免费看| 性生交大片免费看l| 久久精品人人做人人爽97| 久艹视频在线观看| 欧洲国产伦久久久久久久| 亚洲精品一区二区三区蜜桃| 亚洲小视频在线| 丝袜在线视频| 国产精品一区av| 蜜桃一区二区三区| 免费看日b视频| 日本欧美一区二区| 亚洲国产精品无码久久久久高潮 | 免费日韩在线观看| 日韩经典一区二区| 成人av一级片| 国产乱码字幕精品高清av| www.狠狠爱| 精品久久中文字幕| 99在线精品视频免费观看20| 亚洲性日韩精品一区二区| 高清电影在线免费观看| 成人国产在线激情| 红桃成人av在线播放| 欧美 丝袜 自拍 制服 另类| 国产精品一卡二卡在线观看| 999久久久国产| 91国产成人在线| 日韩av视屏| 性欧美视频videos6一9| 久久久久亚洲精品中文字幕| 午夜视频久久久| 日日骚欧美日韩| 可以直接看的无码av| 亚洲国产一区在线观看| 国产露脸91国语对白| 日韩在线欧美在线国产在线| 亚洲精品在线影院| 另类欧美小说| 日韩精品不卡一区二区| 国产91在线视频观看| www.性欧美| 国产乱码久久久久久| 精品国产sm最大网站| 特级毛片在线| av观看久久| 欧美日韩精品一本二本三本| 激情久久综合网| 亚洲毛片av在线| 国产又黄又粗又硬| 久久精品91久久香蕉加勒比| 欧美xxxx免费虐| 91亚洲va在线va天堂va国| 婷婷久久综合| 91香蕉国产线在线观看| 亚洲精品一二三四区| 99热这里是精品| 精品少妇v888av| 99国产精品免费网站| www.好吊操| 99精品久久只有精品| 日韩 欧美 综合| 日韩电影中文字幕在线观看| 北岛玲heyzo一区二区| 美国av一区二区三区| 首页综合国产亚洲丝袜| 国产sm调教视频| 欧美丰满美乳xxx高潮www| 中文在线字幕免费观看| 国产亚洲情侣一区二区无| 香蕉成人久久| 成人免费视频入口| 欧美精品一二三| 久草在线视频福利| 久久青青草原| 青青草国产精品亚洲专区无| 99热6这里只有精品| 日韩精品一区二区三区视频在线观看 | 久久精品夜色噜噜亚洲a∨| 中文字幕av影视| 久久99热精品这里久久精品| 日本欧美高清| 亚洲一级免费在线观看| 一区二区三区在线播放| 午夜视频免费在线| 国产精品夫妻激情| 天堂美国久久| 少妇一级淫免费观看| 欧美日韩在线播放三区| 日本性爱视频在线观看| 免费中文日韩| 国产美女av一区二区三区| 日韩网红少妇无码视频香港| 在线观看亚洲视频| 99久久香蕉| 中文字幕天天干| 亚洲6080在线| 国产婷婷视频在线| 欧美极品一区二区| 九色porny丨国产精品| 日韩成人在线免费视频| 中文字幕日韩高清| 久久久久97| 亚洲精品乱码久久久久久9色| 福利微拍一区二区| 成人日韩欧美| 视频一区二区在线观看|