需要結合:《百度搜索引擎關鍵字URL采集爬蟲優化行業定投方案高效獲得行業流量--筆記篇》 一起看。
1 #!/user/bin/env python
2 # -*- coding:utf-8 -*-
3 # author:隔壁老王
4
5 import requests 6 import re 7
8 def baidu_spider(key,pn): 9 #第一步:確認目標URL: 百度搜索“程序設計”的url
10 #key = '正則表達式'
11 #url = 'https://www.baidu.com/s?wd=%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1&rsv_spt=1&rsv_iqid=0x967855b80019cdd1&issp=1&f=8&rsv_bp=0&rsv_idx=2&ie=utf-8&tn=baiduhome_pg&rsv_enter=0&rsv_sug3=3&rsv_sug1=2&rsv_sug7=100&inputT=643536&rsv_sug4=644636'
12 url = 'https://www.baidu.com/s?&rsv_spt=1&rsv_iqid=0x967855b80019cdd1&issp=1&f=8&rsv_bp=0&rsv_idx=2&ie=utf-8&tn=baiduhome_pg&rsv_enter=0&rsv_sug3=3&rsv_sug1=2&rsv_sug7=100&inputT=643536&rsv_sug4=644636'
13 #優化點 1 這個url被寫死了,如果想爬取其他東西該怎么辦呢
14 fb = open('res\\{}.txt'.format(key), 'w', encoding='utf-8') # 優化點3
15 #優化點 4 實現翻頁
16 for i in range(pn): 17
18 #還有一個請求參數
19 data = {'wd':key,'pn': i * 10} 20
21 #wd=%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1 這個其實就是“程序設計”,是被編碼成這樣子的,搜索的關鍵字
22
23 #第三步:偽裝請求頭,
24 headers = { 25 'User-Agent':r'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'
26 } 27 #字典中的信息在Headers欄的Request Headers下的User-Agent :用來標識用戶類型,是谷歌瀏覽器還是IE瀏覽器等
28
29 #第二步:向第一步中的url發送http請求,要用到requests模塊
30 #這個模塊的安裝,在PyCharm的Terminal命令行中輸入 pip install requests 命令
31 #response = requests.get(url,headers = headers)
32 response = requests.get(url,headers = headers,params = data,timeout = 10) 33 #這里為啥要用GET請求呢,,因為在Headers欄中Request Method:GET 是這里決定的,我們就是在模擬瀏覽器呢,所以瀏覽器用get,我們也要用get
34 #請求完之后一定會收到數據,所以需要定義一個變量接受url返回的數據
35 #response中是很多數據的,很多個信息打包在一起,想要把里邊的信息拿出來,就需要把這個包裹拆開
36 #如果想從這個包裹中讀取到文本信息該如何操作呢?
37 #print(response.text) #這text就是html的所有內容了,就這樣獲取了
38 ''' 打印信息如下: 39 <html> 40 <head> 41 <script> 42 location.replace(location.href.replace("https://","http://")); 43 </script> 44 </head> 45 <body> 46 <noscript><meta http-equiv="refresh" content="0;url=http://www.baidu.com/"></noscript> 47 </body> 48 </html> 49 '''
50 #很明顯出問題了,並沒有返回什么實質性的信息,返回的數據太簡單了
51 #出了什么問題呢?
52 #一個陌生的人打電話找你借錢,你肯定不給,,這里就涉及到網站的反爬,只會把信息返回給合法的用戶,百度有反爬手段拒絕爬蟲的
53 #百度的反爬手段是,在發送http請求的時候,額外帶一點信息,把自己的身份帶上
54 #服務器會根據身份監測 這個請求是不是合法用戶發出來的,如果什么都不寫,requests會自己帶一個信息,告訴對端服務器,我是requests,服務器一看是個爬蟲,就不返回信息給它
55 #所以我們要進行一個偽裝,偽裝一個請求頭,,第三步的內容
56 #做好請求頭之后,把這個headers作為get()的參數,然后再執行腳本,返回的信息就正常了
57
58 #獲取到test信息后,現在再過一遍原理,理解一下為什么要這么干
59
60
61 #第四步:進行數據清洗
62 html = response.text 63 #divs = re.findall(r'<div class="result c-container ".*?</div>',html,re.S) #需要復習一下正則表達式
64 #re.S的作用,如果想讓 正則表達式中的.去匹配不可見字符(換行、回車、空格等)就要帶這個參數
65 #divs是一個列表
66 #print(divs[0])
67 '''
68 <div class="result c-container " id="1" srcid="1599" tpl="se_com_default" data-click="{'rsv_bdr':'0' ,'rsv_cd':'pt:40520|vLevel:3'}" ><h3 class="t"><a 69 data-click="{ 70 'F':'778317EA', 71 'F1':'9D73F1E4', 72 'F2':'4CA6DD6B', 73 'F3':'54E5343F', 74 'T':'1525198098', 75 'y':'3FF3A3FD' 76
77 }" 78 href = "http://www.baidu.com/link?url=dQVdrt2_fgdyKqB1oMjo_CLMibztqwK8-azppn9_Zl8nwZv70cbvRBTuwE4ZqOminSBbbw2-L0Qp5s4ZLQDqujuypHKS1SD4LcOd1S3Rm2PH3Zhz5-vMq1Enkh86pgWV" 79
80 target="_blank" 81
82 ><em>程序設計</em>_百度百科</a></h3><div class="c-abstract"><span class=" newTimeFactor_before_abs m">2015年11月29日 - </span><em>程序設計</em>是給出解決特定問題程序的過程,是軟件構造活動中的重要組成部分。<em>程序設計</em>往往以某種<em>程序設計</em>語言為工具,給出這種語言下的程序。<em>程序設計</em>過程...</div> 83
84 '''
85 #接下來就要獲取 href 中的內容,又要寫正則表達式了,就是把上邊這個url補充完整
86 urls = re.findall(r'<div class="result c-container ".*?"(http://www.baidu.com/link\?url=.*?)".*?</div>',html,re.S) 87 #print(urls[0])
88 #http://www.baidu.com/link?url=zQPLyCOSZWMjz8StrMmgIX5KuIsBnYhCC7vhya7nKbfF9JLvvOqRhYQ2q742zvIzkp2mzoa2REoeaB-b0KO-fSiMlr00E-uXTupL-r2KT0K0w9AfkjCZkcytUOkZ8XQG
89
90 #打印所有的URL
91 #for url in urls:
92 # print(url)
93
94 #http://www.baidu.com/link?url=K0lSFkZ8icMPLoTxXZKvJ_3l0Vt6pVV03ddlCE8Bp37
95
96 #http://www.baidu.com/link?url=K0lSFkZ8icMPLoTxXZKvJ_3l0Vt6pVV03ddlCE8Bp37
97 #真正的url 是 url=K0lSFkZ8icMPLoTxXZKvJ_3l0Vt6pVV03ddlCE8Bp37,,如何獲取這部分內容呢?
98 #這里就體現了requests的強大之處,如果是urllib的話還要處理跳轉
99
100 #獲取真實url 獲取重定向的url
101 #for url in urls:
102 # res = requests.get(url,headers = headers)
103 # print(res.url) #這一步就獲取了真實url
104
105 #http://www.bccn.net/
106
107
108 #上邊數據清洗完之后就要做數據持久化了
109 #數據持久化 把數據寫入到res/程序設計.txt中
110 #這種方式只能寫字符串到文本中
111
112 #數據持久化 寫到文本中
113 #fb = open('res\\程序設計.txt','w',encoding='utf-8')
114
115 #fb = open('res\\{}.txt'.format(key), 'a', encoding='utf-8') # 優化點3
116 #獲取真實url 獲取重定向的url 訪問
117 #for url in urls: #為了避免同名變量的覆蓋,同一個文件中盡量不要使用同名的變量
118 for b_url in urls: 119 res = requests.get(b_url,headers = headers) 120 print(res.url) 121 fb.write(res.url) 122 fb.write('\n') ##write()方法需要手動換行,還可以用writeline()替換
123
124 #fb.close()
125
126 fb.close() 127
128
129 #下一步考慮優化
130 #優化點 1 這個url被寫死了,如果想爬取其他東西該怎么辦呢
131 #優化點 2 防止某個url獲取的過程太耗時,可以設置timeout = 10
132 #優化點 3 根據爬取關鍵字的不同,動態根據關鍵字生成不同的文件
133 #優化點 4 翻頁,所有的翻頁都是a標簽 pn= 用for循環為pn賦值
134 #優化點 5 如果要自定義爬取關鍵字、爬取的頁數,把上面這段代碼封裝成函數
135 #優化點 6 為了避免頻繁打開關閉文件,把文件打開關閉操作放在for循環外
136
137
138 #如果需要同時爬取多個關鍵字,可以用for循環,還可以自定義每個關鍵字的爬取頁數
139 keys = {'正則表達式':5,'美女':'10','爬蟲':12} 140 for key,value in keys.items(): 141 baidu_spider(key,value)
整理后的代碼:
#!/user/bin/env python # -*- coding:utf-8 -*- # author:隔壁老王
import requests import re def baidu_spider(key,pn): url = 'https://www.baidu.com/s?&rsv_spt=1&rsv_iqid=0x967855b80019cdd1&issp=1&f=8&rsv_bp=0&rsv_idx=2&ie=utf-8&tn=baiduhome_pg&rsv_enter=0&rsv_sug3=3&rsv_sug1=2&rsv_sug7=100&inputT=643536&rsv_sug4=644636' fb = open('res\\{}.txt'.format(key), 'w', encoding='utf-8') for i in range(pn): data = {'wd':key,'pn': i * 10} headers = { 'User-Agent':r'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36' } response = requests.get(url,headers = headers,params = data,timeout = 10) html = response.text urls = re.findall(r'<div class="result c-container ".*?"(http://www.baidu.com/link\?url=.*?)".*?</div>',html,re.S) for b_url in urls: res = requests.get(b_url,headers = headers) print(res.url) fb.write(res.url) fb.write('\n') fb.close() keys = {'正則表達式':5,'爬蟲':12} for key,value in keys.items(): baidu_spider(key,value)