寫了兩篇之后,我覺得關於爬蟲,重點還是分析過程
分析些什么呢:
1)首先明確自己要爬取的目標
比如這次我們需要爬取的是使用百度搜索之后所有出來的url結果
2)分析手動進行的獲取目標的過程,以便以程序實現
比如百度,我們先進行輸入關鍵詞搜索,然后百度反饋給我們搜索結果頁,我們再一個個進行點擊查詢
3)思考程序如何實現,並克服實現中的具體困難
那么我們就先按上面的步驟來,我們首先認識到所搜引擎,提供一個搜索框,讓用戶進行輸入,然后點擊執行
我們可以先模擬進行搜索,發現點擊搜索之后的完整url中有一項很關鍵,如下
http://www.baidu.com/s?wd=搜索內容......
后面的內容我們嘗試去除之后再次請求上面的url,發現返回的信息一樣,我們就可以斷定請求的url只需要填入wd這個參數即可
接着我們就應該進行嘗試requests.get()查看是否能正常返回頁面,防止百度的反爬蟲
嘿,幸運的是返回頁面正常哈哈~
(當然如果沒有返回到正常信息,只要設置好headers或者嚴格的cookies就行了)
importrequests
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
importrequestsimportsysimportQueueimportthreadingfrom bs4 importBeautifulSoup as bsimportre
headers={
......
}classbaiduSpider(threading.Thread):def __init__(self,queue,name):
threading.Thread.__init__(self)
self._queue=queue
self._name=namedefrun(self):while notself._queue.empty():
url=self._queue.get()try:
self.get_url(url)exceptException,e:printepass
#一定要異常處理!!!不然中途會停下,爬取的內容就不完整了!!!
defget_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 inurls: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 inf.read():
f= open('E:/url/'+self._name+'.txt','a')
f.write(a.url+'\n')
f.close()defmain(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 inrange(thread_count):
spider=baiduSpider(queue,name)
threads.append(spider)for i inthreads:
i.start()for i inthreads:
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結果手收集就那么多啦!
謝謝觀看哦!