寫了兩篇以後,我以爲關於爬蟲,重點仍是分析過程html
分析些什麼呢:python
1)首先明確本身要爬取的目標cookie
好比此次咱們須要爬取的是使用百度搜索以後全部出來的url結果app
2)分析手動進行的獲取目標的過程,以便以程序實現ide
好比百度,咱們先進行輸入關鍵詞搜索,而後百度反饋給咱們搜索結果頁,咱們再一個個進行點擊查詢工具
3)思考程序如何實現,並克服實現中的具體困難url
那麼咱們就先按上面的步驟來,咱們首先認識到所搜引擎,提供一個搜索框,讓用戶進行輸入,而後點擊執行spa
咱們能夠先模擬進行搜索,發現點擊搜索以後的完整url中有一項很關鍵,以下code
http://www.baidu.com/s?wd=搜索內容......htm
後面的內容咱們嘗試去除以後再次請求上面的url,發現返回的信息同樣,咱們就能夠判定請求的url只須要填入wd這個參數便可
接着咱們就應該進行嘗試requests.get()查看是否能正常返回頁面,防止百度的反爬蟲
嘿,幸運的是返回頁面正常哈哈~
(固然若是沒有返回到正常信息,只要設置好headers或者嚴格的cookies就好了)
import requests url = 'http://www.baidu.com/s?wd=......' r = requests.get(url) print r.status_code,r.content
好,接下來咱們就想知道怎麼爬取全部的結果
我麼再次對url進行分析,發現url中還有一項很關鍵,是控制頁碼的項:
http://www.baidu.com/s?wd=...&pn=x
這個x是每10爲一頁,第一頁爲0,並且一共76頁,也就是750最大值,大於750則返回第一頁
接下來咱們就能夠對抓取到的頁面進行分析
仍是使用友好的beautifulsoup
咱們經過分析發現咱們所須要的url在標籤a中的href裏,並且格式是這樣:
http://www.baidu.com/link?url=......
由於還存在不少別的url混淆,因此咱們只須要進行一個篩選就好了
並且這個得到的url並非咱們想要的url結果,這只是百度的一個跳轉連接
可是讓我欣慰的是,當咱們隊這個跳轉連接進行get請求後,直接返回get對象的url即是咱們想要的結果連接了
而後咱們再次進行嘗試,發現仍是沒有別的反爬蟲機制哈哈
原本的想法是,咱們是否要先進行一個對新的url返回的狀態碼進行一個篩選,不是200就不行(甚至還須要些headers)
可是我發現,其實就算不是200,咱們只要返回請求對象的url就好了,和能不能正常返回不要緊
由於咱們的目的並非請求的頁面結果,而是請求的url
因此只須要所有打印出來就好了
固然我建議寫一個簡單的籠統的headers寫入get,這樣至少能排除一些沒必要要的結果
接着咱們請求的完整思路就差很少了
上代碼:
#coding=utf-8 import requests import sys import Queue import threading from bs4 import BeautifulSoup as bs import re headers = { ...... } class baiduSpider(threading.Thread): def __init__(self,queue,name): threading.Thread.__init__(self) self._queue = queue self._name = name def run(self): while not self._queue.empty(): url = self._queue.get() try: self.get_url(url) except Exception,e: print e pass #必定要異常處理!!!否則中途會停下,爬取的內容就不完整了!!! def get_url(self,url): r = requests.get(url = url,headers = headers) soup = bs(r.content,"html.parser") urls = soup.find_all(name='a',attrs={'href':re.compile(('.'))}) # for i in urls: # print i #抓取百度搜索結果中的a標籤,其中href是包含了百度的跳轉地址 for i in urls: if 'www.baidu.com/link?url=' in i['href']: a = requests.get(url = i['href'],headers = headers) #對跳轉地址進行一次訪問,返回訪問的url就能獲得咱們須要抓取的url結果了 #if a.status_code == 200: #print a.url with open('E:/url/'+self._name+'.txt') as f: if a.url not in f.read(): f = open('E:/url/'+self._name+'.txt','a') f.write(a.url+'\n') f.close() def main(keyword): name = keyword f = open('E:/url/'+name+'.txt','w') f.close() queue = Queue.Queue() for i in range(0,760,10): queue.put('http://www.baidu.com/s?wd=%s&pn=%s'%(keyword,str(i))) threads = [] thread_count = 10 for i in range(thread_count): spider = baiduSpider(queue,name) threads.append(spider) for i in threads: i.start() for i in threads: i.join() print "It's down,sir!" if __name__ == '__main__': if len(sys.argv) != 2: print 'no keyword' print 'Please enter keyword ' sys.exit(-1) else: main(sys.argv[1])
咱們工具的功能就是:
python 123.py keyword
就能將url結果寫入文件
這邊sys我有話講
在if __name__ == '__main__':中先進行一個判斷,若是輸入的字段是一個,那麼咱們就返回提醒信息,讓用戶進行鍵入
若是是兩個,那麼就將第二個鍵入記爲keyword進行操做
固然這邊邏輯有個缺陷,就是大於兩個字符會不會有別的問題(別的問題哦!!!)
值得研究一下,但這不是咱們這篇的重點
好啦,今天的百度url結果手收集就那麼多啦!
謝謝觀看哦!