image
1.系列文章列表
源碼
#!/usr/bin/env python
# -*- coding: utf8 -*-
__author__ = 'van1988ch'
import urllib2
import re
import urlparse
from datetime import datetime
import time
class Throttle:
"""限速,每個域名一個計時器
"""
def __init__(self, delay):
self.delay = delay
self.domains = {}
def wait(self, url):
domain = urlparse.urlparse(url).netloc
last_accessed = self.domains.get(domain)
if self.delay > 0 and last_accessed is not None:
sleep_secs = self.delay - (datetime.now() - last_accessed).seconds
if sleep_secs > 0:
time.sleep(sleep_secs)
self.domains[domain] = datetime.now()
def Download(url, retrynum=2):
"""抓取網(wǎng)頁, retrynum=[500,600)錯誤重試次數(shù)"""
print 'Downloading:', url
try:
html = urllib2.urlopen(url).read()
except urllib2.URLError as e:
print 'Download error:', e.reason
html = None
if retrynum > 0:
if hasattr(e, 'code') and 500 <= e.code < 600:
html = Download(url, retrynum-1)
except :
html = None
return html
def link_crawler(seed_url):
"""分析網(wǎng)頁中的內(nèi)部鏈接來抓取全部網(wǎng)頁
"""
crawl_queue = [seed_url]
seen = set(crawl_queue)
throttle = Throttle(3)
while crawl_queue:
url = crawl_queue.pop()
throttle.wait(url)
html = Download(url)
if html:
for link in get_links(html):
link = urlparse.urljoin(seed_url, link)
if link not in seen:
seen.add(link)
crawl_queue.append(link)
def get_links(html):
"""正則匹配分析出所有的鏈接
"""
webpage_regex = re.compile('<a[^>]+href=["\'](.*?)["\']', re.IGNORECASE)
return webpage_regex.findall(html)
if __name__ == '__main__':
link_crawler('http://www.iplaysoft.com/')
本篇是第三篇文章解決上篇文章的三個問題.
- 1.沒有區(qū)分相對路徑和絕對路徑
- 2.由于計算機請求太快沒有做限速處理,很容易被目標(biāo)主機給屏蔽掉
- 3.沒有對于同一個連接去重
沒有區(qū)分相對路徑和絕對路徑問題
這個問題可以使用python的urlparse這個庫來解決,他可以根據(jù)我們的參數(shù)來決定最終的url.
>>> link = urlparse.urljoin("http://www.baidu.com", "/a")
>>> print link
http://www.baidu.com/a
>>> link = urlparse.urljoin("http://www.baidu.com", "http://www.tytt/a")
>>> print link
http://www.tytt/a
由于計算機請求太快沒有做限速處理,很容易被目標(biāo)主機給屏蔽掉
這個問題是通過Throttle類來處理的.根據(jù)每個域名增加一個計時器來決定是否要延遲本次請求.具體看源代碼
沒有對于同一個連接去重
去重問題就直接交給set來處理的.這樣處理暫時來看沒什么問題,但是其實還是有點粗糙.后面還會介紹基于數(shù)據(jù)庫mongodb來處理去重問題.
2.總結(jié)
這個是一個爬蟲的系列文章,這篇文章只是一個最簡單的爬蟲的代碼,我們會采取由淺到深的這個一個方式來寫這個系列,希望大家多多關(guān)注.github源代碼