自動外鏈工具 在線排版工具 搜索引擎提交入口 wordpress主題推薦 批量打開網址工具 【老域名購買】 思享SEO導航 【網站合作】

Scrapy抓取百度搜索結果頁排名

533

掌握多少知識,就能抓住多少機會。“知識”來源于“信息”的提煉,而“信息”來源于“數據”的分析。從“數據”→“信息”→“知識”→“智慧”是一步步轉化而來。

想從互聯網領域中學習什么東西,不同于學校,老師可以直接給予學生現成的知識。互聯網高速發展、不易預測的特性,導致大部分信息仍處于未知的狀態,沒有多少人會告訴你有什么信息、有什么知識。很多信息還躺在一坨坨數據中等待被分析出來。

所以我覺得,在互聯網行業中,數據獲取與分析是如同溝通表達、時間管理一樣的通用型技能,是可以不受職能控制而進行轉移。

數據可以通過交換、購買、API等方式來獲得,但如果其他人都沒有,那就只能自己去找數據,然后分析出信息,提煉出知識。

舉個例子,曾經為了分析排在百度首頁的網頁都有什么共同特征,自己指定了幾個可能影響排名的因素:網頁大小、下載速度、網頁鏈接數量、正文字數、url的目錄層級、query在正文的出現次數、query分詞后的詞項在正文中的出現次數、query在title中的出現次數等十幾個指標,拿了5000個長尾詞跑百度搜索結果,把前5頁出現的網頁全部抓下來,跑出前面指定的十幾個指標對應的數據,然后分析所處不同分頁的網頁(每個分頁個5萬個樣本),在指標上有什么明顯的規律。

以上是獲取數據,對數據分析后發現:

1、排在第一頁的結果,平均正文字數500,第二頁~第五頁的結果依次遞減;

2、排在第一頁的結果,平均網頁包含的鏈接數量130,第二頁~第五頁的結果依次遞增;

3、其他指標,在所有分頁中均無明顯波動。

 

以上是信息,對信息進行提煉,形成知識:

1、網頁正文字數和網頁包含的鏈接會影響長尾詞的排名

2、覆蓋長尾詞的頁面,保證正文字數控制在500字以上,網頁中包含的鏈接控制在130以下,會提高網頁出現在百度首頁的概率

 

當然,真實的網頁排序因素遠比這個復雜多得多,除了以上兩點肯定還要同時滿足多個條件才能出現在首頁。

另外,還需注意獲取的數據的可靠性和公正性,可靠性是數據能不能推導出正確的結論;公正性是這個數據是不是公平的。

還是上面的例子,如果換成5000個熱詞,那計算出來的結果就不可靠也不公正。因為百度是一個商業搜索引擎,而在長尾詞上,百度會相對不那么商業。

做流量的,很多數據得需要自己去抓,抓取就要用到爬蟲。花了幾天時間體驗了下python的Scrapy,感覺不錯,是一個高性能、易上手、健壯穩定、可高度定制、可分布的爬蟲框架。

作為一個成熟的爬蟲框架,肯定比自己現手寫一個爬蟲要來的快的多,而相比火車頭,它能實現火車頭實現不了的功能,比如上面說的例子。

下面是Scrapy的使用小記

項目構成:

scrapy.cfg:項目配置文件
items.py:存放抓取數據的
pipelines.py:處理抓取數據的
settings.py:爬蟲配置文件,有現成的API,可添加各種防ban策略
middlewares.py:中間件
dmoz_spider.py:爬蟲程序

參照官方文檔和Google寫了個抓取百度排名的程序,上手后,在配置速度比火車頭還要快一些。

考慮百度封閉爬蟲比較嚴,需要一些防屏蔽策略,采用如下方法實現:

1、輪換出口IP

用scrapinghub提供的代理,因為是國外的IP,所以訪問百度比國內要慢一些,但是提供的代理很穩定,方便配置,且免費,貌似沒有使用次數的限制。

在sittings.py中添加:

'''crawlera賬號、密碼'''
CRAWLERA_ENABLED?=?True
CRAWLERA_USER?=?'賬號'
CRAWLERA_PASS?=?'密碼'
'''下載中間件設置'''
DOWNLOADER_MIDDLEWARES?=?{
'scrapy_crawlera.CrawleraMiddleware':?600
}

 

2、輪換UA

在sittings.py添加:

  1. USER_AGENTS = [  
  2.     "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; AcooBrowser; .NET CLR 1.1.4322; .NET CLR 2.0.50727)",  
  3.     "Opera/9.80 (Macintosh; Intel Mac OS X 10.6.8; U; fr) Presto/2.9.168 Version/11.52",  
  4. .......  
  5. ]  
  6. '''下載中間件設置'''  
  7. DOWNLOADER_MIDDLEWARES = {  
  8.     'tutorial.middlewares.RandomUserAgent': 1,  
  9. }  

在middlewares.py添加:

  1. class RandomUserAgent(object):"""Randomly rotate user agents based on a list of predefined ones"""def __init__(self, agents):  
  2.     self.agents = [email protected] from_crawler(cls, crawler):  
  3.     return cls(crawler.settings.getlist('USER_AGENTS'))def process_request(self, request, spider):  
  4.     #print "**************************" + random.choice(self.agents)  
  5.     request.headers.setdefault('User-Agent',   random.choice(self.agents))  

3、輪換Cookie,并完全模擬瀏覽器請求頭

在sittings.py添加:

  1. def getCookie():  
  2.     cookie_list = [  
  3.         'cookie1', #自己從不同瀏覽器中獲取cookie在添加到這  
  4.         'cookie2',  
  5.         ......  
  6. ]  
  7.     cookie = random.choice(cookie_list)  
  8.     return cookie  
  9.   
  10. '''設置默認request headers'''  
  11.   
  12. DEFAULT_REQUEST_HEADERS = {   'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',  
  13.     'Accept-Encoding':'gzip, deflate, sdch',  
  14.     'Accept-Language':'zh-CN,zh;q=0.8,en;q=0.6',  
  15.     'Cache-Control':'max-age=0',  
  16.     'Connection':'keep-alive',  
  17.     'Host':'www.baidu.com',  
  18.     'RA-Sid':'7739A016-20140918-030243-3adabf-48f828',  
  19.     'RA-Ver':'3.0.7',  
  20.     'Upgrade-Insecure-Requests':'1',  
  21.     'Cookie':'%s' % getCookie()  
  22. }  

sittings.py添加其他配置項:

  1. '''下載延時,即下載兩個頁面的等待時間'''  
  2. DOWNLOAD_DELAY = 0.5  
  3.   
  4. '''并發最大值'''  
  5. CONCURRENT_REQUESTS = 100  
  6.   
  7. '''對單個網站并發最大值'''  
  8. CONCURRENT_REQUESTS_PER_DOMAIN = 100  
  9.   
  10. '''啟用AutoThrottle擴展,默認為False'''  
  11. AUTOTHROTTLE_ENABLED = False  
  12.   
  13. '''設置下載超時'''  
  14. DOWNLOAD_TIMEOUT = 10  
  15.   
  16. '''降低log級別,取消注釋則輸出抓取詳情'''  
  17. LOG_LEVEL = 'INFO'  

蜘蛛程序:dmoz_spider.py

  1. class DmozSpider(scrapy.Spider):  
  2.     name = "dmoz"  
  3.     allowed_domains = ["www.baidu.com"]  
  4.   
  5.     # start_urls = ['http://www.baidu.com/s?q=&tn=baidulocal&ct=2097152&si=&ie=utf-8&cl=3&wd=seo%E5%9F%B9%E8%AE%AD']  
  6.   
  7.     start_urls = []  
  8.     for word in open('/Users/sunjian/Desktop/tutorial/tutorial/spiders/word.txt'):  
  9.         word = word.strip()  
  10.         url = 'http://www.baidu.com/s?q=&tn=baidulocal&ct=2097152&si=&ie=utf-8&cl=3&wd=%s' % urllib.quote(word)   
  11.         start_urls.append(url)  
  12.   
  13.     def __get_url_query(self, url):  
  14.             m =  re.search("wd=(.*)", url).group(1)  
  15.             return m  
  16.   
  17.     def parse(self,response):  
  18.             n = 0  
  19.   
  20.             for sel in response.xpath('//td[@class="f"]'):  
  21.   
  22.                 query = urllib.unquote(self.__get_url_query(response.url))  
  23.   
  24.                 item = DmozItem()  
  25.   
  26.                 title = re.sub('<[^>]*?>','',sel.xpath('.//a/font[@size="3"]').extract()[0])  
  27.                 lading = sel.xpath('.//a[1]/@href').extract()[0]  
  28.                 time = sel.xpath('.//font[@color="#008000"]/text()').re('(\d{4}-\d{1,2}-\d{1,2})')[0]  
  29.                 size = sel.xpath('.//font[@color="#008000"]/text()').re('(\d+K)')[0]  
  30.   
  31.                 n += 1  
  32.   
  33.                 item['rank'] = n  
  34.         item['title'] = title.encode('utf8')  
  35.         item['lading'] = lading.encode('utf8')  
  36.         item['time'] = time.encode('utf8')  
  37.         item['size'] = size.encode('utf8')  
  38.         item['query'] = query  
  39.   
  40.         yield item  

抓取數據寫入mysql

在piplines.py添加:

  1. class MySQLTutorialPipeline(object):  
  2.     def __init__(self, dbpool):  
  3.         self.dbpool = dbpool  
  4.       
  5.     @classmethod  
  6.     def from_settings(cls, settings):  
  7.         dbargs = dict(  
  8.             host=settings['MYSQL_HOST'],  
  9.             db=settings['MYSQL_DBNAME'],  
  10.             user=settings['MYSQL_USER'],  
  11.             passwd=settings['MYSQL_PASSWD'],  
  12.             charset='utf8',  
  13.             cursorclass = MySQLdb.cursors.DictCursor,  
  14.             use_unicode= True,  
  15.         )  
  16.         dbpool = adbapi.ConnectionPool('MySQLdb', **dbargs)  
  17.         return cls(dbpool)  
  18.   
  19.     #pipeline默認調用  
  20.     def process_item(self, item, spider):  
  21.         d = self.dbpool.runInteraction(self._do_upinsert, item, spider)  
  22.         d.addErrback(self._handle_error, item, spider)  
  23.         d.addBoth(lambda _: item)  
  24.         return d  
  25.   
  26.     #將每行更新或寫入數據庫中  
  27.     def _do_upinsert(self, conn, item, spider):  
  28.         conn.execute(""" INSERT INTO baidu_pc_rank VALUES ('%s','%s','%s','%s','%s','%s') """ % (item['rank'],item['title'],item['lading'],item['time'],item['size'],item['query']))  
  29.     #獲取url的md5編碼  
  30.     def _get_linkmd5id(self, item):  
  31.         #url進行md5處理,為避免重復采集設計  
  32.         return md5(item['address']).hexdigest()  
  33.     #異常處理  
  34.     def _handle_error(self, failue, item, spider):  
  35.         log.err(failure)  

在settings.py添加:

  1. MYSQL_HOST = '127.0.0.1'  
  2. MYSQL_DBNAME = 'se_rank'  
  3. MYSQL_USER = 'root'  
  4. MYSQL_PASSWD = ''  
  5.   
  6. ITEM_PIPELINES = {  
  7. 'tutorial.pipelines.MySQLTutorialPipeline': 400,  
  8. }  

運行爬蟲:

每分鐘抓300左右個頁面,在速度上仍有很大提升空間,起碼要用國內代理速度會快很多。以上防ban功能適用于所有網站,再抓另一個網站只要做對應修改便可。

抓取數據寫入mysql情況:

 

來源:本文由思享SEO博客原創撰寫,歡迎分享本文,轉載請保留出處和鏈接!
seo培訓評論廣告

搶沙發

昵稱*

郵箱*

網址

七乐彩选号技巧