精品欧美一区二区三区在线观看 _久久久久国色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在线播放 | 免费v片在线观看| 99r国产精品| 国产精品入口日韩视频大尺度 | 精品福利一区二区| 亚洲成色最大综合在线| www.久久成人| 日本va欧美va精品发布| 久久精品国产久精国产一老狼| 91超薄肉色丝袜交足高跟凉鞋| 国产精品亚洲d| 亚洲一区视频在线观看视频| 日韩偷拍一区二区| 老牛影视av牛牛影视av| 久久精品国产精品青草| 欧美专区在线播放| 久久久无码精品亚洲国产| 加勒比久久综合| 精品成人a区在线观看| 91插插插插插插插插| 国产99在线| 亚洲精品伦理在线| 亚洲欧洲在线一区| 美州a亚洲一视本频v色道| 国产成人午夜高潮毛片| 国产免费一区视频观看免费| 国产中文字幕视频| 亚洲国产日韩欧美一区二区三区| 这里只有精品视频| www.中文字幕av| 国内毛片久久| 日韩午夜在线观看视频| 91国内在线播放| 日韩国产网站| 91黄视频在线观看| 六月激情综合网| av中文字幕在线观看第一页| 亚洲一区电影777| 99久久久无码国产精品性色戒| aaa在线观看| 国产日韩欧美一区二区三区乱码| 精品视频在线观看| 日韩一区二区三区不卡| 成人av在线播放网址| 福利视频久久| 东京干手机福利视频| 国产成人三级在线观看| 99国产视频| 懂色av蜜臀av粉嫩av分享吧| 高清日韩电视剧大全免费| 91中文字精品一区二区| 午夜精品久久久久久久爽| 国产福利一区二区三区视频| 99久久精品无码一区二区毛片 | 日本韩国欧美在线观看| 福利影院在线看| 岛国av在线不卡| 精品一卡二卡三卡| 澳门av一区二区三区| 欧美色男人天堂| 青青草久久伊人| 亚洲天堂中文字幕在线观看| 亚洲国产成人精品女人久久久| 欧美xxxx×黑人性爽| 午夜欧洲一区| 亚洲一区二区久久久| 亚洲女同二女同志奶水| 欧美一区二区三区久久精品茉莉花 | 老司机午夜精品视频| 国产成人精品网站| 97精品人妻一区二区三区在线| 久久97超碰色| 成人av蜜桃| 欧美亚洲日本| 国产精品网友自拍| 蜜桃视频一区二区在线观看| 2020国产在线| 欧美视频你懂的| 欧美体内she精高潮| 超碰精品在线| 国产一区二区三区三区在线观看 | 亚洲国产网站| 国产精品海角社区在线观看| 国产女主播福利| a级精品国产片在线观看| 日本一区二区精品| 影音先锋在线视频| 色综合婷婷久久| 一区二区三区国产好的精华液| 高清精品视频| 中文字幕日韩精品在线观看| 久久综合加勒比| 日本成人中文字幕在线视频| 成人免费91在线看| 1024视频在线| 高跟丝袜一区二区三区| 香港日本韩国三级网站| 欧美毛片免费观看| 久久久www成人免费精品| 久久久久99精品成人片三人毛片| 美女爽到高潮91| 精品在线观看一区二区| 超碰在线观看免费版| 欧美视频免费在线| aaaaa黄色片| 日韩欧美精品综合| 91精品91久久久久久| 97国产成人无码精品久久久| 久久久美女毛片| 在线观看免费黄色片| а√天堂资源地址在线下载| 色欧美片视频在线观看| 亚洲调教欧美在线| 午夜日韩电影| 国产欧美韩国高清| 精品av中文字幕在线毛片| 一区二区三区日韩欧美精品| 天天操天天爱天天爽| 欧美一区二区三区红桃小说| 欧美精品一区三区| 亚洲一级视频在线观看| 国产亚洲一本大道中文在线| 日韩中字在线观看| 538任你躁精品视频网免费| 久久精品福利视频| 一区二区视频免费观看| 国产亚洲人成网站| 免费在线观看日韩视频| 欧美电影在线观看免费| 久久久久久久97| 精品国产18久久久久久| 亚洲欧美电影一区二区| 国产三级三级看三级| 国产欧美日韩精品一区二区免费| 91超碰中文字幕久久精品| 少妇一区二区三区四区| 午夜精品久久久久久久99樱桃| 美女又黄又免费的视频| 欧美激情综合色综合啪啪| 亚洲最大av网| 在线观看男女av免费网址| 91精品国产综合久久福利软件| 亚洲aaa视频| 久久99久久99| dy888午夜| 成人h动漫精品一区二区器材| 欧美大码xxxx| 狠狠躁夜夜躁av无码中文幕| 亚洲国产精品久久不卡毛片| 中文字幕18页| 国产日韩欧美高清免费| 欧美日韩在线观看一区二区三区| 中文字幕一区久| 亚洲午夜精品视频| 中文字幕精品在线观看| 亚洲日本在线a| 少妇性l交大片7724com| 亚洲国内欧美| 欧美日韩在线精品| 成人国产一区| 久久偷看各类女兵18女厕嘘嘘| 99国产精品99| 婷婷激情综合网| 免费一级做a爰片久久毛片潮| 日韩成人一区二区| 97精品国产97久久久久久粉红| 最新国产精品精品视频| 欧美在线视频观看| 3p视频在线观看| 精品国产99国产精品| 国产www在线| 国产精品国产三级国产普通话蜜臀| 婷婷中文字幕在线观看| 亚洲日本成人| 亚洲国产精品久久久久婷婷老年| 成人动漫视频在线观看| 欧美亚洲成人精品| 视频三区在线| 亚洲第一精品夜夜躁人人躁| 亚洲图片在线视频| 亚洲三级电影网站| 人妻少妇精品视频一区二区三区 | 国产精品亚洲自拍| 激情图片在线观看高清国产| 一本色道久久88综合亚洲精品ⅰ| 国产绳艺sm调教室论坛| 欧美性生交xxxxx久久久| 亚洲精品电影院| 成人高清免费观看| 一本色道久久亚洲综合精品蜜桃 | 久久久久久美女精品| 国产97在线观看| 黄色大片在线播放| 精品一区二区三区香蕉蜜桃 | 免费男女羞羞的视频网站在线观看| 亚洲国产精品va在看黑人| 中文字幕乱码中文字幕| 亚洲国产三级在线| 亚洲欧美综合7777色婷婷| aaa欧美日韩| 午夜不卡福利视频| 久久国产88| 黄色激情在线视频| 久久精品国产68国产精品亚洲| 国产一区二区无遮挡| 97色婷婷成人综合在线观看| 国产suv精品一区二区| 欧美巨大xxxx做受沙滩| 色噜噜国产精品视频一区二区 | 国产精品白浆| 91亚洲午夜在线| 日本精品在线中文字幕| 97碰在线观看| 免费在线播放电影| 久久精品视频在线播放| 成人免费在线观看| 亚洲精品视频免费在线观看| 亚洲国产成人精品一区二区三区| 欧美精品久久99久久在免费线| 精品不卡一区二区| 午夜久久电影网| 国产亚洲成人精品| 一级做a爱片久久| 久热这里有精品| 国产精品超碰97尤物18| 亚洲图片第一页| 欧美激情一区二区在线| 最近中文字幕在线mv视频在线| 不卡电影一区二区三区| 天堂va欧美va亚洲va老司机| 国产精品亚洲视频| 91香蕉国产线在线观看| 国产一区二区三区免费看| 天天干天天操天天玩| 日本三级亚洲精品| 精品久久久噜噜噜噜久久图片| 先锋a资源在线看亚洲| 国产日韩一区二区在线| 免费国产自线拍一欧美视频| 啊啊啊一区二区| 亚洲影视综合| 99久久久无码国产精品6| 麻豆成人在线| 久久久国产欧美| 奇米在线7777在线精品| 亚洲欧美在线精品| 另类小说欧美激情| 91亚洲一区二区| 国产黄色精品视频| 秋霞午夜一区二区| 日本激情视频在线| 宅男噜噜噜66一区二区| 欧美美女黄色网| 自拍欧美日韩| 黄色网在线视频| 红桃视频国产精品| 奇米影视亚洲色图| 宅男噜噜噜66一区二区| 黄在线观看网站| 日日欢夜夜爽一区| 国产一二三区av| 国内外成人在线| 国产欧美视频一区| 99re视频精品| 精品无码在线观看| 国产精品久久久久久久久动漫 | 欧美在线xxx| 香蕉视频亚洲一级| 国产美女精品免费电影| 视频在线观看免费影院欧美meiju| 国产厕所精品在线观看| 中文字幕精品影院| 影音先锋男人的网站| 日韩视频三区| 最新天堂在线视频| 成人福利视频网站| 欧美人与禽zoz0善交| 亚洲精品乱码久久久久久久久| 青青国产在线观看| 欧美色综合网站| 亚洲精品国产精品乱码不卡| 亚洲精品综合精品自拍| 激情影院在线观看| 人人澡人人澡人人看欧美| 伊人久久一区| 精品国产综合| 亚洲成av人片一区二区密柚| 玩弄中年熟妇正在播放| 精品一区二区三区在线视频| 日韩精品视频一区二区| 国产精品福利一区| 1级黄色大片儿| 欧美精品久久一区二区三区| 亚洲欧美日韩综合在线| 九九精品视频在线| 免费污视频在线一区| 国产精品区一区二区三含羞草| 欧美日韩国产免费观看视频| 男人插女人视频在线观看| 免费成人在线网站| 草草地址线路①屁屁影院成人| 亚洲欧美偷拍另类a∨色屁股| 欧美一级淫片免费视频黄| 欧美成人官网二区| 精精国产xxxx视频在线| 国产精品678| 欧美亚洲国产日韩| 免费看日b视频| 极品少妇xxxx精品少妇| 天天躁日日躁aaaa视频| 午夜国产精品影院在线观看| av免费在线观看不卡| 尤物tv国产一区| 欧美成人a交片免费看| 国产精品久久久久久久久婷婷| 婷婷激情图片久久| 色多多视频在线播放| 久久久久99精品国产片| 日韩欧美成人一区二区三区| 亚洲第一网站男人都懂| 羞羞视频在线观看免费| 91麻豆国产精品| 欧美中文一区二区| 日韩一级免费在线观看| 91麻豆免费视频| 日韩视频免费观看高清| 精品国产乱码久久久久久老虎| 成人免费观看视频大全| 91色在线观看| 久久久久久久久国产一区| 老司机午夜性大片| 国产欧美日韩另类视频免费观看| 日本在线播放视频| 日韩精品久久久久| 在线观看爽视频| 欧日韩一区二区三区| 国产农村妇女精品一二区| 久久久久成人精品无码中文字幕| 亚洲国产成人av网| 色丁香婷婷综合久久| 午夜精品在线视频| 久久1电影院| 成人免费毛片网| 国产午夜精品一区二区| 超碰在线97观看| 日韩中文字幕网| 99视频有精品高清视频| 91精品国产吴梦梦| 成人一区在线观看| 国产福利拍拍拍| 亚洲欧美日韩国产中文专区| 日韩三级影视| 伊人久久av导航| 国产精品一区二区三区99| 精品深夜av无码一区二区老年| 亚洲电影免费观看高清完整版在线| 理论不卡电影大全神| 日本成人三级电影网站| 精品一区二区三区影院在线午夜| 在线免费日韩av| 亚洲精品国产suv| 在线成人视屏| 丰满女人性猛交| 成人av在线资源| 久久精品偷拍视频| 精品国偷自产在线视频| 成人av影音| 超碰在线97免费| 一区二区三区中文字幕在线观看| 人妻视频一区二区三区| 国产精品com| 欧美福利电影在线观看| 国产精品伦子伦| 欧美情侣在线播放| √天堂8资源中文在线| 色999五月色| 国产91精品精华液一区二区三区| 国产午夜在线播放| www亚洲精品| 久久99精品国产自在现线| 久久久久久久久久久久91| 亚洲免费av在线| 欧美女优在线观看| 成人激情视频网| 久久精选视频| 国产又黄又爽又无遮挡| 亚洲精品一区二三区不卡| 99久久999| 乱子伦视频在线看| 一级日本不卡的影视| 成人亚洲综合天堂| 精品一区二区三区自拍图片区 | 在线看三级电影| 欧美日韩国产综合视频在线| 国产剧情av麻豆香蕉精品| 成人午夜淫片100集| 欧美精品一区在线播放| 欧洲杯什么时候开赛| 黄色污在线观看| 日韩欧美在线网站|