開発環境
- macOS Mojave - Apple (OS)
- Emacs (Text Editor)
- Windows 10 Pro (OS)
- Visual Studio Code (Text Editor)
- プログラミング言語
- パッケージ(Python)
プログラミング言語Go (ADDISON-WESLEY PROFESSIONAL COMPUTING SERIES) (Alan A.A. Donovan(著)、Brian W. Kernighan(著)、柴田 芳樹(翻訳)、丸善出版)の第1章(チュートリアル)、1.6(URLからの並行な取得)、練習問題1.11の解答を求めてみる。
alexa.comにあるトップサイトのurl(aタグのhref)の取得にはPythonとパッケージ、requestsとBeautifulSoupを使用。
コード
sample11.go
package main import ( "fmt" "io" "io/ioutil" "net/http" "os" "strings" "time" ) func main() { start := time.Now() ch := make(chan string) for _, url := range os.Args[2:] { if !(strings.HasPrefix(url, "http://") || strings.HasPrefix(url, "https://")) { url = "http://" + url } go fetch(url, ch) } for range os.Args[2:] { fmt.Println(<-ch) } fmt.Printf("%.2fs elapsed\n", time.Since(start).Seconds()) } func fetch(url string, ch chan<- string) { start := time.Now() resp, err := http.Get(url) if err != nil { ch <- fmt.Sprint(err) return } nbytes, err := io.Copy(ioutil.Discard, resp.Body) resp.Body.Close() if err != nil { ch <- fmt.Sprintf("while reading %s: %v", url, err) return } secs := time.Since(start).Seconds() ch <- fmt.Sprintf("%.2fs %7d %s", secs, nbytes, url) }
Python 3
sample11.py
#!/usr/bin/env python3 import os import requests import bs4 domain = 'https://www.alexa.com' html = requests.get('https://www.alexa.com/topsites').text bs_obj = bs4.BeautifulSoup(html, features='lxml') a_tags = bs_obj.find_all('a') urls = [] for link in a_tags: href = link.get('href') if href is not None and href.find('/siteinfo/') != -1: url = href[href.rfind('/') + 1:] urls.append(url) os.execl('./fetchall', *urls)
入出力結果(Terminal, cmd(コマンドプロンプト), Jupyter(IPython))
$ go build -o fetchall sample11.go $ ./sample11.py 0.30s 81 http://baidu.com 0.37s 13252 http://google.co.in 0.39s 101997 http://bing.com 0.41s 12947 http://google.com.hk 0.44s 18906 http://yahoo.co.jp 0.53s 3180 http://t.co 0.57s 182742 http://twitter.com 0.64s 1064 http://reddit.com 0.71s 44329 http://msn.com 0.87s 117147 http://jd.com 0.93s 47708 http://linkedin.com 0.97s 91956 http://ebay.com 1.05s 633944 http://facebook.com 1.16s 237403 http://qq.com 1.25s 3592 http://live.com 1.27s 571629 http://sina.com.cn 1.36s 209047 http://sohu.com 1.38s 11365 http://google.co.jp 1.47s 27942 http://instagram.com 1.50s 78711 http://twitch.tv 1.51s 94478 http://blogspot.com 1.52s 457496 http://amazon.co.jp 1.60s 377433 http://pornhub.com 1.61s 196472 http://livejasmin.com 1.64s 169416 http://microsoft.com 1.67s 80442 http://netflix.com 1.82s 46660 http://csdn.net 1.94s 1338335 http://porn555.com 1.97s 94474 http://weibo.com 1.97s 174695 http://naver.com 2.02s 6400 http://amazon.com 2.09s 83448 http://wikipedia.org 2.09s 227464 http://tribunnews.com 2.11s 243690 http://taobao.com 2.12s 527425 http://yahoo.com 2.17s 199186 http://imdb.com 2.18s 79914 http://github.com 2.29s 75347 http://360.cn 2.32s 247120 http://tmall.com 2.42s 37290 http://aliexpress.com 2.54s 21638 http://alipay.com 2.58s 285497 http://mail.ru 2.70s 13899 http://login.tmall.com 3.04s 9367 http://vk.com 3.51s 114805 http://xvideos.com 3.69s 98597 http://yandex.ru 6.09s 37628 http://pages.tmall.com Get http://microsoftonline.com: dial tcp 40.84.199.233:80: i/o timeout 30.00s elapsed $ echo $? 0 $
ということで、あるウェブサイト(この場合はhttp://microsoftonline.com)が応答しない場合の振る舞いは、fetch関数の一つ目のif文で真になりエラーメッセージ(Get http://microsoftonline.com: dial tcp 40.84.199.233:80: i/o timeout)が出力される。ゴールーチンとチャンネルをしようした場合、最後にメッセージが出力されていて、待たずに応答があって取得できたものから出力されているから、並行に処理されていることが分かる。
0 コメント:
コメントを投稿