亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > Python > 正文

以視頻爬取實例講解Python爬蟲神器Beautiful Soup用法

2020-01-04 17:49:56
字體:
來源:轉載
供稿:網友
這篇文章主要以視頻爬取實例來講解Python爬蟲神器Beautiful Soup的用法,Beautiful Soup是一個為Python獲取數據而設計的包,簡潔而強大,需要的朋友可以參考下
 

1.安裝BeautifulSoup4
easy_install安裝方式,easy_install需要提前安裝

easy_install beautifulsoup4

pip安裝方式,pip也需要提前安裝.此外PyPi中還有一個名字是 BeautifulSoup 的包,那是 Beautiful Soup3 的發布版本.在這里不建議安裝.

pip install beautifulsoup4

Debain或ubuntu安裝方式

apt-get install Python-bs4

你也可以通過源碼安裝,下載BS4源碼

Python setup.py install

2.小試牛刀

# coding=utf-8'''@通過BeautifulSoup下載百度貼吧圖片'''import urllibfrom bs4 import BeautifulSoupurl = 'http://tieba.baidu.com/p/3537654215'# 下載網頁html = urllib.urlopen(url)content = html.read()html.close()# 使用BeautifulSoup匹配圖片html_soup = BeautifulSoup(content)# 圖片代碼我們在[Python爬蟲基礎1--urllib]( http://blog.xiaolud.com/2015/01/22/spider-1st/ "Python爬蟲基礎1--urllib")里面已經分析過了# 相較通過正則表達式去匹配,BeautifulSoup提供了一個更簡單靈活的方式all_img_links = html_soup.findAll('img', class_='BDE_Image')# 接下來就是老生常談的下載圖片img_counter = 1for img_link in all_img_links:  img_name = '%s.jpg' % img_counter  urllib.urlretrieve(img_link['src'], img_name)  img_counter += 1

很簡單,代碼注釋里面已經解釋的很清楚了.BeautifulSoup提供了一個更簡單靈活的方式,去分析網站源碼,更快獲取圖片link.


3.爬取實例
3.1基本的抓取技術

在寫一個爬蟲腳本時,第一件事情就是手動觀察要抓取的頁面來確定數據如何定位。

首先,我們要看一看在 http://pyvideo.org/category/50/pycon-us-2014 上的 PyCon 大會視頻列表。檢查這個頁面的 HTML 源代碼我們發現視頻列表的結果差不多是長這樣的:

<div id="video-summary-content">  <div class="video-summary">  <!-- first video -->    <div class="thumbnail-data">...</div>    <div class="video-summary-data">      <div>        <strong><a href="#link to video page#">#title#</a></strong>      </div>    </div>  </div>  <div class="video-summary">  <!-- second video -->    ...  </div>  ...</div>

那么第一個任務就是加載這個頁面,然后抽取每個單獨頁面的鏈接,因為到 YouTube 視頻的鏈接都在這些單獨頁面上。

使用requests來加載一個 web 頁面是非常簡單的:

import requestsresponse = requests.get('http://pyvideo.org/category/50/pycon-us-2014')

就是它!在這個函數返回后就能從response.text中獲得這個頁面的 HTML 。

下一個任務是抽取每一個單獨視頻頁面的鏈接。通過 BeautifulSoup 使用 CSS 選擇器語法就能完成它,如果你是客戶端開發者的話你可能對這會很熟悉。

為了獲得這些鏈接,我們要使用一個選擇器,它能抓取在每一個 id 為video-summary-data的<div>中所有的<a>元素。由于每個視頻都有幾個<a>元素,我們將只保留那些 URL 以/video開頭的<a>元素,這些就是唯一的單獨視頻頁面。實現上述標準的 CSS 選擇器是div.video-summary-data a[href^=/video]。下面的代碼片段通過 BeautifulSoup 使用這個選擇器來獲得指向視頻頁面的<a>元素:

import bs4soup = bs4.BeautifulSoup(response.text)links = soup.select('div.video-summary-data a[href^=/video]')

因為我們真正關心的是這個鏈接本身而不是包含它的<a>元素,我們可以使用列表解析來改善上述代碼。

links = [a.attrs.get('href') for a in soup.select('div.video-summary-data a[href^=/video]')]
現在,我們已經有了一個包含所有鏈接的數組,這些鏈接指向了每個單獨頁面。

下面這段腳本整理了目前我們提到的所有技術:

import requestsimport bs4root_url = 'http://pyvideo.org'index_url = root_url + '/category/50/pycon-us-2014'def get_video_page_urls():  response = requests.get(index_url)  soup = bs4.BeautifulSoup(response.text)  return [a.attrs.get('href') for a in soup.select('div.video-summary-data a[href^=/video]')]print(get_video_page_urls())

如果你運行上面這段腳本你將會獲得一個滿是 URL 的數組。現在我們需要去解析每個 URL 以獲得更多關于每場 PyCon 會議的信息。

3.2抓取相連頁面
下一步是加載我們的 URL 數組中每一個頁面。如果你想要看看這些頁面長什么樣的話,這兒是個樣例:http://pyvideo.org/video/2668/writing-restful-web-services-with-flask。沒錯,那就是我,那是我會議中的一個!

從這些頁面我們可以抓取到會議的標題,在頁面的頂部能看到它。我們也可以從側邊欄獲得演講者的姓名和 YouTube 的鏈接,側邊欄在嵌入視頻的右下方。獲取這些元素的代碼展示在下方:

def get_video_data(video_page_url):  video_data = {}  response = requests.get(root_url + video_page_url)  soup = bs4.BeautifulSoup(response.text)  video_data['title'] = soup.select('div#videobox h3')[0].get_text()  video_data['speakers'] = [a.get_text() for a in soup.select('div#sidebar a[href^=/speaker]')]  video_data['youtube_url'] = soup.select('div#sidebar a[href^=http://www.youtube.com]')[0].get_text()

關于這個函數需要注意的一些事情:

從首頁抓取的 URL 是相對路徑,所以root_url需要加到前面。
大會標題是從 id 為videobox的<div>里的<h3>元素中獲得的。注意[0]是必須的,因為調用select()返回的是一個數組,即使只有一個匹配。
演講者的姓名和 YouTube 鏈接的獲取方式與首頁上的鏈接獲取方式類似。
現在就剩下從每個視頻的 YouTube 頁面抓取觀看數了。接著上面的函數寫下去其實是非常簡單的。同樣,我們也可以抓取 like 數和 dislike 數。

def get_video_data(video_page_url):  # ...  response = requests.get(video_data['youtube_url'])  soup = bs4.BeautifulSoup(response.text)  video_data['views'] = int(re.sub('[^0-9]', '',                   soup.select('.watch-view-count')[0].get_text().split()[0]))  video_data['likes'] = int(re.sub('[^0-9]', '',                   soup.select('.likes-count')[0].get_text().split()[0]))  video_data['dislikes'] = int(re.sub('[^0-9]', '',                     soup.select('.dislikes-count')[0].get_text().split()[0]))  return video_data

上述調用soup.select()函數,使用指定了 id 名字的選擇器,采集到了視頻的統計數據。但是元素的文本需要被處理一下才能變成數字。考慮觀看數的例子,在 YouTube 上顯示的是"1,344 views"。用一個空格分開(split)數字和文本后,只有第一部分是有用的。由于數字里有逗號,可以用正則表達式過濾掉任何不是數字的字符。

為了完成爬蟲,下面的函數調用了之前提到的所有代碼:

def show_video_stats():  video_page_urls = get_video_page_urls()  for video_page_url in video_page_urls:    print get_video_data(video_page_url)

3.3并行處理
上面到目前為止的腳本工作地很好,但是有一百多個視頻它就要跑個一會兒了。事實上我們沒做什么工作,大部分時間都浪費在了下載頁面上,在這段時間腳本時被阻塞的。如果腳本能同時跑多個下載任務,可能就會更高效了,是嗎?

回顧當時寫一篇使用 Node.js 的爬蟲文章的時候,并發性是伴隨 JavaScript 的異步特性自帶來的。使用 Python 也能做到,不過需要顯示地指定一下。像這個例子,我將開啟一個擁有8個可并行化進程的進程池。代碼出人意料的簡潔:

from multiprocessing import Pooldef show_video_stats(options):  pool = Pool(8)  video_page_urls = get_video_page_urls()  results = pool.map(get_video_data, video_page_urls)

multiprocessing.Pool 類開啟了8個工作進程等待分配任務運行。為什么是8個?這是我電腦上核數的兩倍。當時實驗不同大小的進程池時,我發現這是最佳的大小。小于8個使腳本跑的太慢,多于8個也不會讓它更快。

調用pool.map()類似于調用常規的map(),它將會對第二個參數指定的迭代變量中的每個元素調用一次第一個參數指定的函數。最大的不同是,它將發送這些給進程池所擁有的進程運行,所以在這個例子中八個任務將會并行運行。

節省下來的時間是相當大的。在我的電腦上,第一個版本的腳本用了75秒完成,然而進程池的版本做了同樣的工作只用了16秒!

3.4完成爬蟲腳本
我最終版本的爬蟲腳本在獲得數據后還做了更多的事情。

我添加了一個--sort命令行參數去指定一個排序標準,可以指定views,likes或者dislikes。腳本將會根據指定屬性對結果數組進行遞減排序。另一個參數,--max代表了要顯示的結果數的個數,萬一你只想看排名靠前的幾條而已。最后,我還添加了一個--csv選項,為了可以輕松地將數據導到電子制表軟件中,可以指定數據以 CSV 格式打印出來,而不是表對齊格式。

完整腳本顯示在下方:

import argparseimport refrom multiprocessing import Poolimport requestsimport bs4root_url = 'http://pyvideo.org'index_url = root_url + '/category/50/pycon-us-2014'def get_video_page_urls():  response = requests.get(index_url)  soup = bs4.BeautifulSoup(response.text)  return [a.attrs.get('href') for a in soup.select('div.video-summary-data a[href^=/video]')]def get_video_data(video_page_url):  video_data = {}  response = requests.get(root_url + video_page_url)  soup = bs4.BeautifulSoup(response.text)  video_data['title'] = soup.select('div#videobox h3')[0].get_text()  video_data['speakers'] = [a.get_text() for a in soup.select('div#sidebar a[href^=/speaker]')]  video_data['youtube_url'] = soup.select('div#sidebar a[href^=http://www.youtube.com]')[0].get_text()  response = requests.get(video_data['youtube_url'])  soup = bs4.BeautifulSoup(response.text)  video_data['views'] = int(re.sub('[^0-9]', '',                   soup.select('.watch-view-count')[0].get_text().split()[0]))  video_data['likes'] = int(re.sub('[^0-9]', '',                   soup.select('.likes-count')[0].get_text().split()[0]))  video_data['dislikes'] = int(re.sub('[^0-9]', '',                    soup.select('.dislikes-count')[0].get_text().split()[0]))  return video_datadef parse_args():  parser = argparse.ArgumentParser(description='Show PyCon 2014 video statistics.')  parser.add_argument('--sort', metavar='FIELD', choices=['views', 'likes', 'dislikes'],            default='views',            help='sort by the specified field. Options are views, likes and dislikes.')  parser.add_argument('--max', metavar='MAX', type=int, help='show the top MAX entries only.')  parser.add_argument('--csv', action='store_true', default=False,            help='output the data in CSV format.')  parser.add_argument('--workers', type=int, default=8,            help='number of workers to use, 8 by default.')  return parser.parse_args()def show_video_stats(options):  pool = Pool(options.workers)  video_page_urls = get_video_page_urls()  results = sorted(pool.map(get_video_data, video_page_urls), key=lambda video: video[options.sort],           reverse=True)  max = options.max  if max is None or max > len(results):    max = len(results)  if options.csv:    print(u'"title","speakers", "views","likes","dislikes"')  else:    print(u'Views +1 -1 Title (Speakers)')  for i in range(max):    if options.csv:      print(u'"{0}","{1}",{2},{3},{4}'.format(        results[i]['title'], ', '.join(results[i]['speakers']), results[i]['views'],        results[i]['likes'], results[i]['dislikes']))    else:      print(u'{0:5d} {1:3d} {2:3d} {3} ({4})'.format(        results[i]['views'], results[i]['likes'], results[i]['dislikes'], results[i]['title'],        ', '.join(results[i]['speakers'])))if __name__ == '__main__':  show_video_stats(parse_args())

下方輸出的是在我寫完代碼時前25個觀看數最多的會議:

(venv) $ python pycon-scraper.py --sort views --max 25 --workers 8Views +1 -1 Title (Speakers) 3002 27  0 Keynote - Guido Van Rossum (Guido Van Rossum) 2564 21  0 Computer science fundamentals for self-taught programmers (Justin Abrahms) 2369 17  0 Ansible - Python-Powered Radically Simple IT Automation (Michael Dehaan) 2165 27  6 Analyzing Rap Lyrics with Python (Julie Lavoie) 2158 24  3 Exploring Machine Learning with Scikit-learn (Jake Vanderplas, Olivier Grisel) 2065 13  0 Fast Python, Slow Python (Alex Gaynor) 2024 24  0 Getting Started with Django, a crash course (Kenneth Love) 1986 47  0 It's Dangerous to Go Alone: Battling the Invisible Monsters in Tech (Julie Pagano) 1843 24  0 Discovering Python (David Beazley) 1672 22  0 All Your Ducks In A Row: Data Structures in the Standard Library and Beyond (Brandon Rhodes) 1558 17  1 Keynote - Fernando Pérez (Fernando Pérez) 1449  6  0 Descriptors and Metaclasses - Understanding and Using Python's More Advanced Features (Mike Müller) 1402 12  0 Flask by Example (Miguel Grinberg) 1342  6  0 Python Epiphanies (Stuart Williams) 1219  5  0 0 to 00111100 with web2py (G. Clifford Williams) 1169 18  0 Cheap Helicopters In My Living Room (Ned Jackson Lovely) 1146 11  0 IPython in depth: high productivity interactive and parallel python (Fernando Perez) 1127  5  0 2D/3D graphics with Python on mobile platforms (Niko Skrypnik) 1081  8  0 Generators: The Final Frontier (David Beazley) 1067 12  0 Designing Poetic APIs (Erik Rose) 1064  6  0 Keynote - John Perry Barlow (John Perry Barlow) 1029 10  0 What Is Async, How Does It Work, And When Should I Use It? (A. Jesse Jiryu Davis) 981 11  0 The Sorry State of SSL (Hynek Schlawack) 961 12  2 Farewell and Welcome Home: Python in Two Genders (Naomi Ceder) 958  6  0 Getting Started Testing (Ned Batchelder)

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产成人精品999| 欧美与黑人午夜性猛交久久久| 国产91av在线| 国产精品欧美激情在线播放| 成人黄色大片在线免费观看| 亚洲天堂av在线免费观看| 亚洲精品综合久久中文字幕| 久久久久久久亚洲精品| 国产精品亚洲аv天堂网| 日韩精品中文字幕在线观看| 日本不卡高字幕在线2019| 国产又爽又黄的激情精品视频| 色视频www在线播放国产成人| 久久久国产91| 欧美日韩福利在线观看| 最近免费中文字幕视频2019| 久久五月情影视| 在线观看国产欧美| 91精品久久久久久久久久另类| 91社影院在线观看| 大胆欧美人体视频| 欧美视频精品一区| 欲色天天网综合久久| 欧美高清第一页| 国产精品色午夜在线观看| 久久久久久久久久久网站| 久久久亚洲影院你懂的| 亚洲精品美女久久久久| 欧美国产日产韩国视频| 亚洲欧美激情一区| 国产一区深夜福利| 国产日韩欧美成人| 国模极品一区二区三区| 国产99久久精品一区二区 夜夜躁日日躁| 欧美日韩成人在线播放| 国产精品永久在线| 亚洲天堂日韩电影| 国产精品一区二区三区在线播放| 欧美精品一区在线播放| 国产精品久久久久久久久久久久久久| 亚洲视频网站在线观看| 一区二区三区天堂av| 欧美一区二区.| 91免费看片网站| 日韩欧美在线网址| 欧美精品在线播放| 亚洲品质视频自拍网| www.欧美免费| 久久久久久久亚洲精品| 日韩电影视频免费| 亚洲精品98久久久久久中文字幕| 国产精品视频一区二区高潮| 91九色综合久久| 精品无码久久久久久国产| 亚洲电影免费观看高清完整版在线观看| 国产suv精品一区二区| 色999日韩欧美国产| 久久婷婷国产麻豆91天堂| 久久亚洲综合国产精品99麻豆精品福利| 亚洲自拍av在线| 91精品国产99久久久久久| 理论片在线不卡免费观看| 日韩av在线天堂网| 综合网中文字幕| 成人国产在线激情| 中文字幕精品久久| 中文字幕在线观看日韩| 日本高清视频一区| 亚洲wwwav| 日韩成人av在线| 亚洲色图在线观看| 国产婷婷成人久久av免费高清| 欧美福利视频在线观看| 日韩中文字幕不卡视频| 日韩精品在线视频观看| 欧美肥婆姓交大片| 亚洲国产婷婷香蕉久久久久久| 97**国产露脸精品国产| 色妞欧美日韩在线| 日韩电影中文字幕| 亚洲一区第一页| 亚洲国产天堂网精品网站| 免费97视频在线精品国自产拍| 亚洲欧美精品一区| 欧美电影免费观看高清完整| 欧美激情视频免费观看| 国产亚洲激情在线| 亚洲男人第一网站| 成人在线观看视频网站| 亚洲大尺度美女在线| 亚洲免费高清视频| 一二美女精品欧洲| 伊人久久精品视频| 国产午夜精品一区二区三区| 久久精品国产亚洲一区二区| 欧美日韩国产中文精品字幕自在自线| 成人黄色免费看| 日韩精品视频中文在线观看| 欧美日韩不卡合集视频| 精品一区二区三区三区| 亚洲成人激情在线| 日韩电视剧在线观看免费网站| 精品性高朝久久久久久久| 日韩成人中文字幕在线观看| 日韩av影视综合网| 亚洲精品美女久久久| 国产盗摄xxxx视频xxx69| 九九热最新视频//这里只有精品| 不卡中文字幕av| 国产精品观看在线亚洲人成网| 亚洲少妇激情视频| 国产最新精品视频| 91视频免费在线| 欧美视频专区一二在线观看| 国产精品日韩在线播放| 日韩亚洲欧美成人| 久久久久久成人精品| 国产精品视频男人的天堂| 日韩美女av在线| 国产精品亚洲自拍| 亚洲区中文字幕| 欧美视频在线观看 亚洲欧| 欧美日韩精品在线视频| 91国偷自产一区二区三区的观看方式| 久久噜噜噜精品国产亚洲综合| 最近2019年日本中文免费字幕| 亚洲一区中文字幕| 成人亚洲激情网| 精品视频久久久久久久| 一区二区亚洲欧洲国产日韩| 欧洲日韩成人av| 日韩视频亚洲视频| 国产成人av网址| 91久久久久久久| 视频一区视频二区国产精品| 国产精品96久久久久久又黄又硬| 欧美精品在线免费| 国产精品自产拍高潮在线观看| 国内精品久久影院| 国产精品美女999| 欧美一级电影免费在线观看| 国产999精品久久久| 中文字幕一区电影| 国产91精品久久久久| 日韩精品视频免费专区在线播放| 亚洲va男人天堂| 国产精品96久久久久久| 亚洲精品一区二区三区不| 日韩av在线影视| 欧美大片在线影院| 亚洲美女性生活视频| 久久亚洲影音av资源网| 日韩精品在线免费| 色先锋资源久久综合5566| 午夜精品三级视频福利| 正在播放国产一区| 成人午夜激情网| 在线日韩第一页| 国产成人午夜视频网址| 国产精品99免视看9| 亚洲xxxx18| 亚洲成人xxx| 欧美第一黄网免费网站| 欧美国产日本在线|