Python開發簡單爬蟲

Python開發簡單爬蟲

         源碼網址:  http://download.csdn.NET/detail/hanchaobiao/9860671
html


1、爬蟲的簡介及爬蟲技術價值

       1.什麼是爬蟲


         一段自動抓取互聯網信息的程序,能夠從一個URL出發,訪問它所關聯的URL,提取咱們所須要的數據。也就是說爬蟲是自動訪問互聯網並提取數據的程序。node


           

         2.爬蟲的價值

     將互聯網上的數據爲我所用,開發出屬於本身的網站或APP


簡單的網絡爬蟲流程架 


  爬蟲調度端:用來啓動、執行、中止爬蟲,或者監視爬蟲中的運行狀況
  在爬蟲程序中有三個模塊URL管理器:對將要爬取的URL和已經爬取過的URL這兩個數據的管理
  網頁下載器:將URL管理器裏提供的一個URL對應的網頁下載下來,存儲爲一個字符串,這個字符串會傳送給網頁解析器進行解析
  網頁解析器:一方面會解析出有價值的數據,另外一方面,因爲每個頁面都有不少指向其它頁面的網頁,這些URL被解析出來以後,能夠補充進URL管理 器
  這三部門就組成了一個簡單的爬蟲架構,這個架構就能將互聯網中全部的網頁抓取下來
python


   動態執行流程



     

3、URL管理器及三種實現方式


    防止重複抓取和循環抓取,最嚴重狀況兩個URL相互指向就會造成死循環mysql

    

    三種實現方式redis

    Python內存set集合:set集合支持去重的做用sql

    MySQLurl(訪問路徑)is_crawled(是否訪問)python3.x

    Redis:使用redis性能最好,且Redis中也有set類型,能夠去重。不懂得同窗能夠看下Redis的介紹數組

                   

4、網頁下載器和urlib模塊 cookie

   本文使用urllib實現網絡

   urllib2python自帶的模塊,不須要下載。
   urllib2python3.x中被改成urllib.request

           

         三種實現方式

            方法一:

[python] view plain copy

  1. #引入模塊  

  2. from urllib import request  

  3. url = "http://www.baidu.com"  

  4.   

  5. #第一種下載網頁的方法  

  6. print("第一種方法:")  

  7. #request = urllib.urlopen(url)  2.x  

  8. response1 = request.urlopen(url)  

  9. print("狀態碼:",response1.getcode())  

  10. #獲取網頁內容  

  11. html = response1.read()  

  12. #設置編碼格式  

  13. print(html.decode("utf8"))  

  14. #關閉response1  

  15. response1.close()  


   

   方法二:

[python] view plain copy

  1. print("第二種:")  

  2. request2 = request.Request(url)  

  3. request2.add_header('user-agent','Mozilla/5.0')  

  4. response2 = request.urlopen(request2)  

  5. print("狀態碼:",response2.getcode())  

  6. #獲取網頁內容  

  7. htm2 = response2.read()  

  8. #調整格式  

  9. print(htm2.decode("utf8"))  

  10. #關閉response1  

  11. response2.close()  



   方法三:使用cookie

[html] view plain copy

  1. <span style="font-size:12px;">#第三種方法 使用cookie獲取  

  2. import http.cookiejar  

  3. cookie = http.cookiejar.LWPCookieJar()  

  4. opener = request.build_opener(request.HTTPCookieProcessor(cookie))  

  5. request.install_opener(opener)  

  6. response3 = request.urlopen(url)  

  7. print(cookie)  

  8. html3 = response3.read()  

  9. #將內容格式排列  

  10. print(html3.decode("utf8"))  

  11. response3.close()</span>  



5、網頁解析器和BeautifulSoup第三方模塊

           

             


             測試是否安裝bs4

        

[python] view plain copy

  1. import bs4  

  2. print(bs4)  

  3.   

  4. 打印結果:<module 'bs4' from 'D:\\app\\Python\\Anaconda\\lib\\site-packages\\bs4\\__init__.py'>  

  5. 則安裝成功  


         Beautiful Soup 相比其餘的html解析有個很是重要的優點。html會被拆解爲對象處理。全篇轉化爲字典和數組。


         相比正則解析的爬蟲,省略了學習正則的高成本,本文使用python3.x系統自帶不須要安裝。

         使用案例:http://blog.csdn.net/watsy/article/details/14161201


           方法介紹




     實例測試

                html採用官方案例






[python] view plain copy

  1. #引用模塊  

  2. from bs4 import BeautifulSoup  

  3.   

  4. html_doc = """   

  5. <html><head><title>The Dormouse's story</title></head>   

  6. <body>   

  7. <p class="title"><b>The Dormouse's story</b></p>   

  8.  

  9. <p class="story">Once upon a time there were three little sisters; and their names were   

  10. <a href="http://example.com/elsie" class="sister" id="link1">Elsie</a>,   

  11. <a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and   

  12. <a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>;   

  13. and they lived at the bottom of a well.</p>   

  14. <p class="story">...</p>   

  15. """  


      獲取全部的連接



[python] view plain copy

  1. print("獲取全部的連接")  

  2. links = soup.find_all('a')  #a標籤  

  3. for link in links:  

  4.     print(link.name,link['href'],link.get_text())  


[python] view plain copy

  1. #獲取href=http://example.com/lacie的連接  

  2. print("獲取lacie連接")  

  3. link1 = soup.find('a',href="http://example.com/lacie")  

  4. print(link1.name,link1['href'],link1.get_text())  



[python] view plain copy

  1. print("正則匹配 href中帶有「ill」的")  

  2. import re #導入re包  

  3. link2 = soup.find('a',href=re.compile(r"ill"))  

  4. print(link2.name,link2['href'],link2.get_text())  


[python] view plain copy

  1. print("獲取p段落文字")  

  2. link3 = soup.find('p',class_="title"#class是關鍵字 須要加_  

  3. print(link3.name,link3.get_text())  



6、爬蟲開發實例(目標爬蟲百度百科)

           

            入口:http://baike.baidu.com/item/Python

           分析URL格式:防止訪問無用路徑 http://baike.baidu.com/item/{標題}

           數據:抓取百度百科相關Python詞條網頁的標題和簡介

                       經過審查元素得標題元素爲 :class="lemmaWgt-lemmaTitle-title"

                       簡介元素爲:class="lemma-summary"

            頁面編碼:UTF-8

            做爲定向爬蟲網站要根據爬蟲的內容升級而升級如運行出錯可能爲百度百科升級,此時則須要從新分析目標

            代碼集註釋:

            建立spider_main.py


[python] view plain copy

  1. #建立類  

  2. from imooc.baike_spider import url_manager,html_downloader,html_output,html_parser  

  3. class spiderMain:  

  4.     #構造函數 初始化  

  5.     def __init__(self):  

  6.         #實例化需引用的對象  

  7.         self.urls = url_manager.UrlManager()  

  8.         self.downloader = html_downloader.HtmlDownLoader()  

  9.         self.output = html_output.HtmlOutPut()  

  10.         self.parser = html_parser.HtmlParser()  

  11.   

  12.     def craw(self,root_url):  

  13.         #添加一個到url中  

  14.         self.urls.add_new_url(root_url)  

  15.         count = 1  

  16.         while self.urls.has_new_url():  

  17.             try:  

  18.                 new_url = self.urls.get_new_url()  

  19.                 print('craw %d : %s' %(count,new_url))  

  20.                 #下載  

  21.                 html_context = self.downloader.downloade(new_url)  

  22.                 new_urls,new_data = self.parser.parse(new_url,html_context)  

  23.                 print(new_urls)  

  24.                 self.urls.add_new_urls(new_urls)  

  25.                 self.output.collect_data(new_data)  

  26.                 #爬一千個界面  

  27.                 if(count==1000):  

  28.                     break  

  29.                 count+=1  

  30.             except:  

  31.                 print("craw faile")  

  32.         self.output.output_html()  

  33.   

  34.   

  35. #建立main方法  

  36. if __name__ == "__main__":  

  37.     root_url = "http://baike.baidu.com/item/Python"  

  38.     obj_spider = spiderMain()  

  39.     obj_spider.craw(root_url)  



     建立url_manager.py


[python] view plain copy

  1. class UrlManager:  

  2.     'url管理類'  

  3.     #構造函數初始化set集合  

  4.     def __init__(self):  

  5.         self.new_urls = set() #待爬取的url  

  6.         self.old_urls = set() #已爬取的url  

  7.   

  8.     #向管理器中添加一個新的url  

  9.     def add_new_url(self,root_url):  

  10.         if(root_url is None):  

  11.             return  

  12.         if(root_url not in self.new_urls and root_url not in self.old_urls):  

  13.             #既不在待爬取的url也不在已爬取的url中,是一個全新的url,所以將其添加到new_urls  

  14.             self.new_urls.add(root_url)  

  15.   

  16.     # 向管理器中添加批量新的url  

  17.     def add_new_urls(self,urls):  

  18.         if(urls is None or len(urls) == 0):  

  19.             return  

  20.         for url in urls:  

  21.             self.add_new_url(url) #調用add_new_url()  

  22.   

  23.     #判斷是否有新的待爬取的url  

  24.     def has_new_url(self):  

  25.         return len(self.new_urls) != 0  

  26.     #獲取一個待爬取的url  

  27.     def get_new_url(self):  

  28.         new_url = self.new_urls.pop()  

  29.         self.old_urls.add(new_url)  

  30.         return new_url  



    建立html_downloader.py


[python] view plain copy <span style="font-size:12px;">from urllib import request  from urllib.parse import quote  import string  class HtmlDownLoader:      '下載頁面內容'      def downloade(self,new_url):          if(new_url is None):              return None          #解決請求路徑中含義中文或特殊字符          url_ = quote(new_url, safe=string.printable);          response = request.urlopen(url_)          if(response.getcode()!=200):              return None #請求失敗          html = response.read()          return html.decode("utf8")</span>


       建立html_parser.py


[python] view plain copy

  1. from bs4 import BeautifulSoup  

  2. import re  

  3. from urllib import parse  

  4. class HtmlParser:  

  5.     #page_url 基本url 需拼接部分  

  6.     def _get_new_urls(self,page_url,soup):  

  7.         new_urls = set()  

  8.         #匹配 /item/%E8%87%AA%E7%94%B1%E8%BD%AF%E4%BB%B6  

  9.         links = soup.find_all('a',href=re.compile(r'/item/\w+'))  

  10.         for link in links:  

  11.             new_url = link["href"]  

  12.             #例如page_url=http://baike.baidu.com/item/Python new_url=/item/史記·2016?fr=navbar  

  13.             #則使用parse.urljoin(page_url,new_url)後 new_full_url = http://baike.baidu.com/item/史記·2016?fr=navbar  

  14.             new_full_url = parse.urljoin(page_url,new_url)  

  15.             new_urls.add(new_full_url)  

  16.         return new_urls  

  17.   

  18.     def _get_new_data(self,page_url,soup):  

  19.         #<dd class="lemmaWgt-lemmaTitle-title"> <h1>Python</h1>  

  20.         red_data = {}  

  21.         red_data['url'] = page_url  

  22.         title_node = soup.find('dd',class_="lemmaWgt-lemmaTitle-title").find('h1'#獲取標題內容  

  23.         red_data['title'] = title_node.get_text()  

  24.         #<div class="lemma-summary" label-module="lemmaSummary">  

  25.         summary_node = soup.find('div',class_="lemma-summary")  

  26.         red_data['summary'] = summary_node.get_text()  

  27.         return red_data  

  28.   

  29.   

  30.   

  31.     #new_url路徑 html_context界面內容  

  32.     def parse(self,page_url, html_context):  

  33.         if(page_url is None or html_context is None):  

  34.             return  

  35.         #python3缺省的編碼是unicode, 再在from_encoding設置爲utf8, 會被忽視掉,去掉【from_encoding = "utf-8"】這一個好了  

  36.         soup = BeautifulSoup(html_context, "html.parser")  

  37.         new_urls = self._get_new_urls(page_url, soup)  

  38.         new_data = self._get_new_data(page_url, soup)  

  39.         return new_urls,new_data  


       建立html_output.py


[python] view plain copy

  1. class HtmlOutPut:  

  2.     def __init__(self):  

  3.         self.datas = [] #存放蒐集的數據  

  4.     def collect_data(self,new_data):  

  5.         if(new_data is None):  

  6.             return  

  7.         self.datas.append(new_data)  

  8.   

  9.     def output_html(self):  

  10.         fout = open('output.html','w',encoding='utf8')  #寫入文件 防止中文亂碼  

  11.         fout.write('<html>\n')  

  12.         fout.write('<body>\n')  

  13.         fout.write('<table>\n')  

  14.         for data in self.datas:  

  15.             fout.write('<tr>\n')  

  16.             fout.write('<td>%s</td>\n'%data['url'])  

  17.             fout.write('<td>%s</td>\n'%data['title'])  

  18.             fout.write('<td>%s</td>\n'%data['summary'])  

  19.             fout.write('</tr>\n')  

  20.         fout.write('</table>\n')  

  21.         fout.write('</body>\n')  

  22.         fout.write('</html>\n')  

  23.         fout.close()  


視頻網站:http://www.imooc.com/learn/563


源碼網址:http://download.csdn.Net/detail/hanchaobiao/9860671

相關文章
相關標籤/搜索