摘要:概述這是一個網絡爬蟲學習的技術分享,主要通過一些實際的案例對爬蟲的原理進行分析,達到對爬蟲有個基本的認識,并且能夠根據自己的需要爬到想要的數據。
概述
這是一個網絡爬蟲學習的技術分享,主要通過一些實際的案例對爬蟲的原理進行分析,達到對爬蟲有個基本的認識,并且能夠根據自己的需要爬到想要的數據。有了數據后可以做數據分析或者通過其他方式重新結構化展示。
什么是網絡爬蟲網絡爬蟲(又被稱為網頁蜘蛛,網絡機器人,在FOAF社區中間,更經常的稱為網頁追逐者),是一種按照一定的規則,自動地抓取萬維網信息的程序或者腳本。另外一些不常使用的名字還有螞蟻、自動索引、模擬程序或者蠕蟲。via?百度百科網絡爬蟲
網絡蜘蛛(Web spider)也叫網絡爬蟲(Web crawler),螞蟻(ant),自動檢索工具(automatic indexer),或者(在FOAF軟件概念中)網絡疾走(WEB scutter),是一種“自動化瀏覽網絡”的程序,或者說是一種網絡機器人。它們被廣泛用于互聯網搜索引擎或其他類似網站,以獲取或更新這些網站的內容和檢索方式。它們可以自動采集所有其能夠訪問到的頁面內容,以供搜索引擎做進一步處理(分檢整理下載的頁面),而使得用戶能更快的檢索到他們需要的信息。via?維基百科網絡蜘蛛
以上是百度百科和維基百科對網絡爬蟲的定義,簡單來說爬蟲就是抓取目標網站內容的工具,一般是根據定義的行為自動進行抓取,更智能的爬蟲會自動分析目標網站結構類似與搜索引擎的爬蟲,我們這里只討論基本的爬蟲原理。
爬蟲工作原理網絡爬蟲框架主要由控制器、解析器和索引庫三大部分組成,而爬蟲工作原理主要是解析器這個環節,解析器的主要工作是下載網頁,進行頁面的處理,主要是將一些JS腳本標簽、CSS代碼內容、空格字符、HTML標簽等內容處理掉,爬蟲的基本工作是由解析器完成。所以解析器的具體流程是:
分析爬蟲目標結構入口訪問->下載內容->分析結構->提取內容
這里我們通過分析一個網站[落網:http://luoo.net] 對網站內容進行提取來進一步了解!
第一步 確定目的
抓取目標網站的某一期所有音樂
第二步 分析頁面結構
訪問落網的某一期刊,通過Chrome的開發者模式查看播放列表中的歌曲,右側用紅色框線圈出來的是一些需要特別注意的語義結構,見下圖所示:
以上紅色框線圈出的地方主要有歌曲名稱,歌曲的編號等,這里并沒有看到歌曲的實際文件地址,所以我們繼續查看,點擊某一個歌曲就會立即在瀏覽器中播放,這時我們可以看到在Chrome的開發者模式的Network中看到實際請求的播放文件,如下圖所示:
根據以上分析我們可以得到播放清單的位置和音樂文件的路徑,接下來我們通過Python來實現這個目的。
實現爬蟲Python環境安裝請自行Google
主要依賴第三方庫
Requests(http://www.python-requests.org) 用來發起請求
BeautifulSoup(bs4) 用來解析HTML結構并提取內容
faker(http://fake-factory.readthedocs.io/en/stable/)用來模擬請求UA(User-Agent)
主要思路是分成兩部分,第一部分用來發起請求分析出播放列表然后丟到隊列中,第二部分在隊列中逐條下載文件到本地,一般分析列表速度更快,下載速度比較慢可以借助多線程同時進行下載。
主要代碼如下:
#-*- coding: utf-8 -*- """by sudo rm -rf http://imchenkun.com""" import os import requests from bs4 import BeautifulSoup import random from faker import Factory import Queue import threading fake = Factory.create() luoo_site = "http://www.luoo.net/music/" luoo_site_mp3 = "http://luoo-mp3.kssws.ks-cdn.com/low/luoo/radio%s/%s.mp3" proxy_ips = [ "27.15.236.236" ] # 替換自己的代理IP headers = { "Connection": "keep-alive", "User-Agent": fake.user_agent() } def random_proxies(): ip_index = random.randint(0, len(proxy_ips)-1) res = { "http": proxy_ips[ip_index] } return res def fix_characters(s): for c in ["<", ">", ":", """, "/", "", "|", "?", "*"]: s = s.replace(c, "") return s class LuooSpider(threading.Thread): def __init__(self, url, vols, queue=None): threading.Thread.__init__(self) print "[luoo spider]" print "=" * 20 self.url = url self.queue = queue self.vol = "1" self.vols = vols def run(self): for vol in self.vols: self.spider(vol) print " crawl end " def spider(self, vol): url = luoo_site + vol print "crawling: " + url + " " res = requests.get(url, proxies=random_proxies()) soup = BeautifulSoup(res.content, "html.parser") title = soup.find("span", attrs={"class": "vol-title"}).text cover = soup.find("img", attrs={"class": "vol-cover"})["src"] desc = soup.find("div", attrs={"class": "vol-desc"}) track_names = soup.find_all("a", attrs={"class": "trackname"}) track_count = len(track_names) tracks = [] for track in track_names: _id = str(int(track.text[:2])) if (int(vol) < 12) else track.text[:2] # 12期前的音樂編號1~9是1位(如:1~9),之后的都是2位 1~9會在左邊墊0(如:01~09) _name = fix_characters(track.text[4:]) tracks.append({"id": _id, "name": _name}) phases = { "phase": vol, # 期刊編號 "title": title, # 期刊標題 "cover": cover, # 期刊封面 "desc": desc, # 期刊描述 "track_count": track_count, # 節目數 "tracks": tracks # 節目清單(節目編號,節目名稱) } self.queue.put(phases) class LuooDownloader(threading.Thread): def __init__(self, url, dist, queue=None): threading.Thread.__init__(self) self.url = url self.queue = queue self.dist = dist self.__counter = 0 def run(self): while True: if self.queue.qsize() <= 0: pass else: phases = self.queue.get() self.download(phases) def download(self, phases): for track in phases["tracks"]: file_url = self.url % (phases["phase"], track["id"]) local_file_dict = "%s/%s" % (self.dist, phases["phase"]) if not os.path.exists(local_file_dict): os.makedirs(local_file_dict) local_file = "%s/%s.%s.mp3" % (local_file_dict, track["id"], track["name"]) if not os.path.isfile(local_file): print "downloading: " + track["name"] res = requests.get(file_url, proxies=random_proxies(), headers=headers) with open(local_file, "wb") as f: f.write(res.content) f.close() print "done. " else: print "break: " + track["name"] if __name__ == "__main__": spider_queue = Queue.Queue() luoo = LuooSpider(luoo_site, vols=["680", "721", "725", "720"],queue=spider_queue) luoo.setDaemon(True) luoo.start() downloader_count = 5 for i in range(downloader_count): luoo_download = LuooDownloader(luoo_site_mp3, "D:/luoo", queue=spider_queue) luoo_download.setDaemon(True) luoo_download.start()
以上代碼執行后結果如下圖所示
Github地址:https://github.com/imchenkun/ick-spider/blob/master/luoospider.py
通過本文我們基本了解了網絡爬蟲的知識,對網絡爬蟲工作原理認識的同時我們實現了一個真實的案例場景,這里主要是使用一些基礎的第三方Python庫來幫助我們實現爬蟲,基本上演示了網絡爬蟲框架中基本的核心概念。通常工作中我們會使用一些比較優秀的爬蟲框架來快速的實現需求,比如 scrapy框架,接下來我會通過使用Scrapy這類爬蟲框架來實現一個新的爬蟲來加深對網絡爬蟲的理解!
特別申明:本文所提到的落網是我本人特別喜歡的一個音樂網站,本文只是拿來進行爬蟲的技術交流學習,讀者涉及到的所有侵權問題都與本人無關
本文首發在sudo rm -rf 采用署名(BY)-非商業性使用(NC)-禁止演繹(ND) 轉載請注明原作者
--EOF--
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/38063.html
摘要:不過不用擔心,中有很多非常優秀的爬蟲框架,比如我們接下來要學習到的。結合以上分析我們基本確定了本次爬蟲的各個路線入口,接下來我們就開始通過程序來實現本次的目標。這里我們的目的是建立一種寫爬蟲的思路,而不在于怎么使用工具來爬數據。 概述 在上一篇文章《爬蟲學習之一個簡單的網絡爬蟲》中我們對爬蟲的概念有了一個初步的認識,并且通過Python的一些第三方庫很方便的提取了我們想要的內容,但是...
摘要:概述在前面兩篇爬蟲學習之基于的網絡爬蟲和爬蟲學習之簡單的網絡爬蟲文章中我們通過兩個實際的案例,采用不同的方式進行了內容提取。 概述 在前面兩篇(爬蟲學習之基于Scrapy的網絡爬蟲和爬蟲學習之簡單的網絡爬蟲)文章中我們通過兩個實際的案例,采用不同的方式進行了內容提取。我們對網絡爬蟲有了一個比較初級的認識,只要發起請求獲取響應的網頁內容,然后對內容進行格式化存儲。很多時候我們抓取到的內容...
摘要:為什么我會說它們是一樣的簡單思考一下我的后端書架后端掘金我的后端書架月前本書架主要針對后端開發與架構。一方案調研版本選擇當前主流版本是和應用的后臺運行配置后端掘金醬油一篇,整理一下關于后臺運行的一些配置方式。 分享 50 個完整的 React Native 項目 - 掘金本文為 Marno 原創,轉載必須保留出處! 公眾號 aMarno,關注后回復 RN 加入交流群 簡書專題《 Rea...
摘要:時間永遠都過得那么快,一晃從年注冊,到現在已經過去了年那些被我藏在收藏夾吃灰的文章,已經太多了,是時候把他們整理一下了。那是因為收藏夾太亂,橡皮擦給設置私密了,不收拾不好看呀。 ...
閱讀 1165·2021-11-25 09:43
閱讀 2979·2019-08-30 15:54
閱讀 3363·2019-08-30 15:54
閱讀 3013·2019-08-30 15:44
閱讀 1636·2019-08-26 12:18
閱讀 2266·2019-08-26 11:42
閱讀 887·2019-08-26 11:35
閱讀 3306·2019-08-23 18:22