<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                文章主要講述如何通過Python爬取維基百科的消息盒(Infobox),主要是通過正則表達式和urllib實現;后面的文章可能會講述通過BeautifulSoup實現爬取網頁知識。由于這方面的文章還是較少,希望提供一些思想和方法對大家有所幫助。如果有錯誤或不足之處,歡迎之處;如果你只想知道該篇文章最終代碼,建議直接閱讀第5部分及運行截圖。 ##一. 維基百科和Infobox 你可能會疑惑Infobox究竟是個什么東西呢?下面簡單介紹。 維基百科作為目前規模最大和增長最快的開放式的在線百科系統,其典型包括兩個網狀結構:文章網絡和分類樹(以樹為主體的圖)。該篇博客主要是對維基百科“程序語言”結構進行分析,下載網頁后提取相關消息盒(Infobox)中屬性和對應的值。 Infobox是模板(一系列的信息框),通常是成對的標簽label和數據data組成。參考:[http://zh.wikipedia.org/wiki/Template:Infobox](http://zh.wikipedia.org/wiki/Template:Infobox) 下圖是維基百科“世界政區索引”中“中國”的部分Infobox信息和“程序設計語言列表”的“ACL2”語言的消息盒。 ![](https://box.kancloud.cn/2016-02-23_56cc2eb2da6e1.jpg) ?![](https://box.kancloud.cn/2016-02-23_56cc2eb2ee00e.jpg) ##二. 爬蟲實現 ###1. python下載html網頁 首先需要訪問維基百科的“程序設計語言列表”,并簡單講述如何下載靜態網頁的代碼。在維基百科中輸入如下URL可以獲取所有程序語言列表: [http://zh.wikipedia.org/wiki/程序設計語言列表](http://zh.wikipedia.org/wiki/程序設計語言列表) 你可以看到從A到Z的各種程序語言,如A#.NET、ActionScript、C++、易語言等,當然可能其中很多語言都沒有完善或沒有消息盒Infobox。同樣如果你想查詢世界各個國家的信息,輸入URL如下: [http://zh.wikipedia.org/wiki/世界政區索引](http://zh.wikipedia.org/wiki/世界政區索引) 通過如下代碼可以獲取靜態的html頁面: ~~~ # coding=utf-8 import urllib import time import re #第一步 獲取維基百科內容 #http://zh.wikipedia.org/wiki/程序設計語言列表 keyname="程序設計語言列表" temp='http://zh.wikipedia.org/wiki/'+str(keyname) content = urllib.urlopen(temp).read() open('wikipedia.html','w+').write(content) print 'Start Crawling pages!!!' ~~~ 獲取的本地wikipedia.html界面如下圖所示: ![](https://box.kancloud.cn/2016-02-23_56cc2eb30d281.jpg) ##2. 正則表達式獲取URL超鏈 現在需要通過Python正則表達式獲取所有語言的超鏈接URL。 網頁中創建超鏈接需要使用A標記符,結束標記符為</A>.它的最基本屬性是href,用于指定超鏈接的目標,通過href屬性指定不同的值,可以創建不同類型的超鏈接. ~~~ href = '<p><a href="www.csdn.cn" title="csdn">CSDN</a></p>' link = re.findall(r"(?<=href=\").+?(?=\")|(?<=href=\').+?(?=\')", href) print link ~~~ 上面是獲取網頁URL的正則表達式代碼,輸出結果是:['www.csdn.cn']。 但是獲取“程序設計語言列表”中所有語言時,我是通過人工確定起始位置“0-9”和結束位置“參看”進行查找的,代碼如下: ~~~ # coding=utf-8 import urllib import time import re #第一步 獲取維基百科內容 #http://zh.wikipedia.org/wiki/程序設計語言列表 keyname="程序設計語言列表" temp='http://zh.wikipedia.org/wiki/'+str(keyname) content = urllib.urlopen(temp).read() open('wikipedia.html','w+').write(content) print 'Start Crawling pages!!!' #第二步 獲取網頁中的所有URL #從原文中"0-9"到"參看"之間是A-Z各個語言的URL start=content.find(r'0-9') end=content.find(r'參看') cutcontent=content[start:end] link_list = re.findall(r"(?<=href=\").+?(?=\")|(?<=href=\').+?(?=\')", cutcontent) fileurl=open('test.txt','w') for url in link_list: print url ~~~ 輸出的結果HTML源碼主要包括以下幾種形式: ~~~ <a href="#A">A</a> <a href="/wiki/C%EF%BC%83" title="C#" class="mw-redirect">C#</a> <a href="/w/index.php?title=..." class="new" title="A Sharp (.NET)(頁面不存在)">A# .NET</a> 輸出: #A /wiki/C%EF%BC%83 /w/index.php?title=A%2B%2B&amp;action=edit&amp;redlink=1. ~~~ 此時獲取了href中URL,很顯然“http://zh.wikipedia.org”加上獲取的后綴就是具體的一門語言信息,如: [http://zh.wikipedia.org/wiki/C#](http://zh.wikipedia.org/wiki/C%E2%99%AF) [](http://zh.wikipedia.org/wiki/C%E2%99%AF) [http://zh.wikipedia.org/wiki/A_Sharp_(.NET)](http://zh.wikipedia.org/wiki/A_Sharp_(.NET))? 它會轉換成C%EF%..等形式。而index.php?此種形式表示該頁面維基百科未完善,相應的Infobox消息盒也是不存在的。下面就是去到每一個具體的URL獲取里面的title信息,同時下載相應的靜態URL。 ##3. 獲取程序語言title信息及下載html 首先通過拼接成完整的URL,在通過open函數下載對應的程序語言html源碼至language文件夾下;再通過正則表達式r'(?<=<title>).*?(?=</title>)'可以獲取網頁的title信息。代碼如下: ~~~ # coding=utf-8 import urllib import time import re #第一步 獲取維基百科內容 #http://zh.wikipedia.org/wiki/程序設計語言列表 keyname="程序設計語言列表" temp='http://zh.wikipedia.org/wiki/'+str(keyname) content = urllib.urlopen(temp).read() open('wikipedia.html','w+').write(content) print 'Start Crawling pages!!!' #第二步 獲取網頁中的所有URL #從原文中"0-9"到"參看"之間是A-Z各個語言的URL start=content.find(r'0-9') end=content.find(r'參看') cutcontent=content[start:end] link_list = re.findall(r"(?<=href=\").+?(?=\")|(?<=href=\').+?(?=\')", cutcontent) fileurl=open('test.txt','w') for url in link_list: #字符串包含wiki或/w/index.php則正確url 否則A-Z if url.find('wiki')>=0 or url.find('index.php')>=0: fileurl.write(url+'\n') #print url num=num+1 fileurl.close() print 'URL Successed! ',num,' urls.' #第三步 下載每個程序URL靜態文件并獲取Infobox對應table信息 #國家:http://zh.wikipedia.org/wiki/阿布哈茲 #語言:http://zh.wikipedia.org/wiki/ActionScript info=open('infobox.txt','w') info.write('********獲取程序語言信息*******\n\n') j=1 for url in link_list: if url.find('wiki')>=0 or url.find('index.php')>=0: #下載靜態html wikiurl='http://zh.wikipedia.org'+str(url) print wikiurl language = urllib.urlopen(wikiurl).read() name=str(j)+' language.html' #注意 需要創建一個country的文件夾 否則總報錯No such file or directory open(r'language/'+name,'w+').write(language) #寫方式打開+沒有即創建 #獲取title信息 title_pat=r'(?<=<title>).*?(?=</title>)' title_ex=re.compile(title_pat,re.M|re.S) title_obj=re.search(title_ex, language) #language對應當前語言HTML所有內容 title=title_obj.group() #獲取內容'C語言 - 維基百科,自由的百科全書' 僅獲取語言名 middle=title.find(r'-') info.write('【程序語言 '+title[:middle]+'】\n') print title[:middle] #設置下載數量 j=j+1 time.sleep(1) if j==20: break; else: print 'Error url!!!' else: print 'Download over!!!' ~~~ 輸出結果如下圖所示,其中獲取20個程序語言URL的標題輸入infobox.txt如下: ![](https://box.kancloud.cn/2016-02-23_56cc2eb32379c.jpg) ? ? ? 然后是獲取每門語言HTML下載至本地的language文件夾下,需要自己創建一個文件夾。其中一門語言代碼如下,標題就是下圖左上方的ACL2: ![](https://box.kancloud.cn/2016-02-23_56cc2eb33aa3e.jpg) ##4. 爬取class=Infobox的table信息 獲取Infobox的table信息,通過分析源代碼發現“程序設計語言列表”的消息盒如下: ~~~ <table class="infobox vevent" ..><tr><th></th><td></td></tr></table> ~~~ 而“世界政區索引”的消息盒形式如下: ~~~ ? ??<table class="infobox"><tr><td></td></tr></table> ~~~ 具體的代碼如下所示: ~~~ # coding=utf-8 import urllib import time import re #第一步 獲取維基百科內容 #http://zh.wikipedia.org/wiki/程序設計語言列表 keyname="程序設計語言列表" temp='http://zh.wikipedia.org/wiki/'+str(keyname) content = urllib.urlopen(temp).read() open('wikipedia.html','w+').write(content) print 'Start Crawling pages!!!' #第二步 獲取網頁中的所有URL #從原文中"0-9"到"參看"之間是A-Z各個語言的URL start=content.find(r'0-9') end=content.find(r'參看') cutcontent=content[start:end] link_list = re.findall(r"(?<=href=\").+?(?=\")|(?<=href=\').+?(?=\')", cutcontent) fileurl=open('test.txt','w') for url in link_list: #字符串包含wiki或/w/index.php則正確url 否則A-Z if url.find('wiki')>=0 or url.find('index.php')>=0: fileurl.write(url+'\n') #print url num=num+1 fileurl.close() print 'URL Successed! ',num,' urls.' #第三步 下載每個程序URL靜態文件并獲取Infobox對應table信息 #國家:http://zh.wikipedia.org/wiki/阿布哈茲 #語言:http://zh.wikipedia.org/wiki/ActionScript info=open('infobox.txt','w') info.write('********獲取程序語言信息*******\n\n') j=1 for url in link_list: if url.find('wiki')>=0 or url.find('index.php')>=0: #下載靜態html wikiurl='http://zh.wikipedia.org'+str(url) print wikiurl language = urllib.urlopen(wikiurl).read() name=str(j)+' language.html' #注意 需要創建一個country的文件夾 否則總報錯No such file or directory open(r'language/'+name,'w+').write(language) #寫方式打開+沒有即創建 #獲取title信息 title_pat=r'(?<=<title>).*?(?=</title>)' title_ex=re.compile(title_pat,re.M|re.S) title_obj=re.search(title_ex, language) #language對應當前語言HTML所有內容 title=title_obj.group() #獲取內容'C語言 - 維基百科,自由的百科全書' 僅獲取語言名 middle=title.find(r'-') info.write('【程序語言 '+title[:middle]+'】\n') print title[:middle] #第四步 獲取Infobox的內容 #標準方法是通過<table>匹配</table>確認其內容,找與它最近的一個結束符號 #但此處分析源碼后取巧<p><b>實現 start=language.find(r'<table class="infobox vevent"') #起點記錄查詢位置 end=language.find(r'<p><b>'+title[:middle-1]) #減去1個空格 infobox=language[start:end] print infobox #設置下載數量 j=j+1 time.sleep(1) if j==20: break; else: print 'Error url!!!' else: print 'Download over!!!' ~~~ ? ? ? “print infobox”輸出其中一門語言ActionScript的InfoBox消息盒部分源代碼如下: ~~~ <table class="infobox vevent" cellspacing="3" style="border-spacing:3px;width:22em;text-align:left;font-size:small;line-height:1.5em;"> <caption class="summary"><b>ActionScript</b></caption> <tr> <th scope="row" style="text-align:left;white-space:nowrap;;;">發行時間</th> <td style=";;">1998年</td> </tr> <tr> <th scope="row" style="text-align:left;white-space:nowrap;;;">實現者</th> <td class="organiser" style=";;"><a href="/wiki/Adobe_Systems" title="Adobe Systems">Adobe Systems</a></td> </tr> <tr> <tr> <th scope="row" style="text-align:left;white-space:nowrap;;;">啟發語言</th> <td style=";;"><a href="/wiki/JavaScript" title="JavaScript">JavaScript</a>、<a href="/wiki/Java" title="Java">Java</a></td> </tr> </table> ~~~ ##5. 爬取消息盒屬性-屬性值 爬取格式如下: ~~~ <table> <tr> <th>屬性</th> <td></td> </tr> </table> ~~~ 其中th表示加粗處理,td和th中可能存在屬性如title、id、type等值;同時<td></td>之間的內容可能存在<a href=..></a>或<span></span>或<br />等值,都需要處理。下面先講解正則表達式獲取td值的例子: 參考:[http://bbs.csdn.net/topics/390353859?page=1](http://bbs.csdn.net/topics/390353859?page=1) ~~~ <table> <tr> <td>序列號</td><td>DEIN3-39CD3-2093J3</td> <td>日期</td><td>2013年1月22日</td> <td>售價</td><td>392.70 元</td> <td>說明</td><td>僅限5用戶使用</td> </tr> </table> ~~~ Python代碼如下: ~~~ s = '''<table> .... </table>''' #對應上面HTML res = r'<td>(.*?)</td><td>(.*?)</td>' m = re.findall(res,s,re.S|re.M) for line in m: print unicode(line[0],'utf-8'),unicode(line[1],'utf-8') #unicode防止亂碼 #輸出結果如下: #序列號 DEIN3-39CD3-2093J3 #日期 2013年1月22日 #售價 392.70 元 #說明 僅限5用戶使用 ~~~ 如果<td id="">包含該屬性則正則表達式為r'<td id=.*?>(.*?)</td>';同樣如果不一定是id屬性開頭,則可以使用正則表達式r'<td .*?>(.*?)</td>'。 最終代碼如下: ~~~ # coding=utf-8 import urllib import time import re #第一步 獲取維基百科內容 #http://zh.wikipedia.org/wiki/程序設計語言列表 keyname="程序設計語言列表" temp='http://zh.wikipedia.org/wiki/'+str(keyname) content = urllib.urlopen(temp).read() open('wikipedia.html','w+').write(content) print 'Start Crawling pages!!!' #第二步 獲取網頁中的所有URL #從原文中"0-9"到"參看"之間是A-Z各個語言的URL start=content.find(r'0-9') end=content.find(r'參看') cutcontent=content[start:end] link_list = re.findall(r"(?<=href=\").+?(?=\")|(?<=href=\').+?(?=\')", cutcontent) fileurl=open('test.txt','w') for url in link_list: #字符串包含wiki或/w/index.php則正確url 否則A-Z if url.find('wiki')>=0 or url.find('index.php')>=0: fileurl.write(url+'\n') #print url num=num+1 fileurl.close() print 'URL Successed! ',num,' urls.' #第三步 下載每個程序URL靜態文件并獲取Infobox對應table信息 #國家:http://zh.wikipedia.org/wiki/阿布哈茲 #語言:http://zh.wikipedia.org/wiki/ActionScript info=open('infobox.txt','w') info.write('********獲取程序語言信息*******\n\n') j=1 for url in link_list: if url.find('wiki')>=0 or url.find('index.php')>=0: #下載靜態html wikiurl='http://zh.wikipedia.org'+str(url) print wikiurl language = urllib.urlopen(wikiurl).read() name=str(j)+' language.html' #注意 需要創建一個country的文件夾 否則總報錯No such file or directory open(r'language/'+name,'w+').write(language) #寫方式打開+沒有即創建 #獲取title信息 title_pat=r'(?<=<title>).*?(?=</title>)' title_ex=re.compile(title_pat,re.M|re.S) title_obj=re.search(title_ex, language) #language對應當前語言HTML所有內容 title=title_obj.group() #獲取內容'C語言 - 維基百科,自由的百科全書' 僅獲取語言名 middle=title.find(r'-') info.write('【程序語言 '+title[:middle]+'】\n') print title[:middle] #第四步 獲取Infobox的內容 #標準方法是通過<table>匹配</table>確認其內容,找與它最近的一個結束符號 #但此處分析源碼后取巧<p><b>實現 start=language.find(r'<table class="infobox vevent"') #起點記錄查詢位置 end=language.find(r'<p><b>'+title[:middle-1]) #減去1個空格 infobox=language[start:end] #print infobox #第五步 獲取table中屬性-屬性值 if "infobox vevent" in language: #防止無Infobox輸出多余換行 #獲取table中tr值 res_tr = r'<tr>(.*?)</tr>' m_tr = re.findall(res_tr,infobox,re.S|re.M) for line in m_tr: #print unicode(line,'utf-8') #獲取表格第一列th 屬性 res_th = r'<th scope=.*?>(.*?)</th>' m_th = re.findall(res_th,line,re.S|re.M) for mm in m_th: #如果獲取加粗的th中含超鏈接則處理 if "href" in mm: restr = r'<a href=.*?>(.*?)</a>' h = re.findall(restr,mm,re.S|re.M) print unicode(h[0],'utf-8') info.write(h[0]+'\n') else: #報錯用str()不行 針對兩個類型相同的變量 #TypeError: coercing to Unicode: need string or buffer, list found print unicode(mm,'utf-8') #unicode防止亂 info.write(mm+'\n') #獲取表格第二列td 屬性值 res_td = r'<td .*?>(.*?)</td>' m_td = re.findall(res_td,line,re.S|re.M) for nn in m_td: if "href" in nn: #處理超鏈接<a href=../rel=..></a> res_value = r'<a .*?>(.*?)</a>' m_value = re.findall(res_value,nn,re.S|re.M) #m_td會出現TypeError: expected string or buffer for value in m_value: print unicode(value,'utf-8'), info.write(value+' ') print ' ' #換行 info.write('\n') else: print unicode(nn,'utf-8') info.write(nn+'\n') print '\n' info.write('\n\n') else: print 'No Infobox\n' info.write('No Infobox\n\n\n') #設置下載數量 j=j+1 time.sleep(1) if j==40: break; else: print 'Error url!!!' else: print 'Download over!!!' ~~~ 輸出結果是自定義爬取多少門語言,其中Ada編程語言如下圖所示: ![](https://box.kancloud.cn/2016-02-23_56cc2eb351f4d.jpg) 最初我采用的是如下方法,維基百科需要中文繁體,需要人工標注分析HTML再爬取兩個尖括號(>...<)之間的內容: ~~~ #啟發語言 start=infobox.find(r'啟發語言') end=infobox.find(r'</tr>',start) print infobox[start:end] info.write(infobox[start:end]+'\n') ~~~ 當然代碼中還存在很多小問題,比如爬取的信息中含<a href>超鏈接時只能爬取含超鏈接的信息,而沒有超鏈接的信息被忽略了;如何刪除<span class="noprint"></span>或<br/>等信息。但是我希望自己能提供一種爬取網頁知識的方法給大家分享,后面可能會講述如何通過Python實現BeautifulSoup爬取網頁知識以及如何爬取圖片,很多時候我們在野網站瀏覽圖片都需要不斷點擊下一張。 (By:Eastmount 2015-3-18 深夜4點 ?[http://blog.csdn.net/eastmount/](http://blog.csdn.net/eastmount/))
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看