欢迎访问 生活随笔!

ag凯发k8国际

当前位置: ag凯发k8国际 > 编程语言 > python >内容正文

python

[python学习] 简单爬取维基百科程序语言消息盒 -ag凯发k8国际

发布时间:2024/5/28 python 79 豆豆
ag凯发k8国际 收集整理的这篇文章主要介绍了 [python学习] 简单爬取维基百科程序语言消息盒 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

        文章主要讲述如何通过python爬取维基百科的消息盒(infobox),主要是通过正则表达式和urllib实现;后面的文章可能会讲述通过beautifulsoup实现爬取网页知识。由于这方面的文章还是较少,希望提供一些思想和方法对大家有所帮助。如果有错误或不足之处,欢迎之处;如果你只想知道该篇文章最终代码,建议直接阅读第5部分及运行截图。

一. 维基百科和infobox

        你可能会疑惑infobox究竟是个什么东西呢?下面简单介绍。
        维基百科作为目前规模最大和增长最快的开放式的在线百科系统,其典型包括两个网状结构:文章网络和分类树(以树为主体的图)。该篇博客主要是对维基百科“程序语言”结构进行分析,下载网页后提取相关消息盒(infobox)中属性和对应的值。
        infobox是模板(一系列的信息框),通常是成对的标签label和数据data组成。参考:http://zh.wikipedia.org/wiki/template:infobox
        下图是维基百科“世界政区索引”中“中国”的部分infobox信息和“程序设计语言列表”的“acl2”语言的消息盒。

  

二. 爬虫实现


        1. python下载html网页

        首先需要访问维基百科的“程序设计语言列表”,并简单讲述如何下载静态网页的代码。在维基百科中输入如下url可以获取所有程序语言列表:
        http://zh.wikipedia.org/wiki/程序设计语言列表
        你可以看到从a到z的各种程序语言,如a# .net、actionscript、c 、易语言等,当然可能其中很多语言都没有完善或没有消息盒infobox。同样如果你想查询世界各个国家的信息,输入url如下:
        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界面如下图所示:

        2. 正则表达式获取url超链接

        现在需要通过python正则表达式获取所有语言的超链接url。
        网页中创建超链接需要使用a标记符,结束标记符为.它的最基本属性是href,用于指定超链接的目标,通过href属性指定不同的值,可以创建不同类型的超链接.
href = '' 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 输出: #a /wiki/c# /w/index.php?title=a++&action=edit&redlink=1.         此时获取了href中url,很显然“http://zh.wikipedia.org”加上获取的后缀就是具体的一门语言信息,如:         http://zh.wikipedia.org/wiki/c#         http://zh.wikipedia.org/wiki/a_sharp_(.net)         它会转换成c�%..等形式。而index.php?此种形式表示该页面维基百科未完善,相应的infobox消息盒也是不存在的。下面就是去到每一个具体的url获取里面的title信息,同时下载相应的静态url。

        3. 获取程序语言title信息及下载html

        首先通过拼接成完整的url,在通过open函数下载对应的程序语言html源码至language文件夹下;再通过正则表达式r'(?<=).*?(?=)'可以获取网页的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-zif url.find('wiki')>=0 or url.find('index.php')>=0: fileurl.write(url '\n')#print urlnum=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:#下载静态htmlwikiurl='http://zh.wikipedia.org' str(url)print wikiurllanguage = urllib.urlopen(wikiurl).read()name=str(j) ' language.html'#注意 需要创建一个country的文件夹 否则总报错no such file or directoryopen(r'language/' name,'w ').write(language) #写方式打开 没有即创建#获取title信息title_pat=r'(?<=).*?(?=)'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 1time.sleep(1)if j==20:break;else:print 'error url!!!' else:print 'download over!!!'        输出结果如下图所示,其中获取20个程序语言url的标题输入infobox.txt如下:
        然后是获取每门语言html下载至本地的language文件夹下,需要自己创建一个文件夹。其中一门语言代码如下,标题就是下图左上方的acl2:

        4. 爬取class=infobox的table信息

        获取infobox的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-zif url.find('wiki')>=0 or url.find('index.php')>=0: fileurl.write(url '\n')#print urlnum=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:#下载静态htmlwikiurl='http://zh.wikipedia.org' str(url)print wikiurllanguage = urllib.urlopen(wikiurl).read()name=str(j) ' language.html'#注意 需要创建一个country的文件夹 否则总报错no such file or directoryopen(r'language/' name,'w ').write(language) #写方式打开 没有即创建#获取title信息title_pat=r'(?<=).*?(?=)'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的内容#标准方法是通过匹配
确认其内容,找与它最近的一个结束符号#但此处分析源码后取巧

实现start=language.find(r'

' title[:middle-1]) #减去1个空格infobox=language[start:end]print infobox#设置下载数量j=j 1time.sleep(1)if j==20:break;else:print 'error url!!!' else:print 'download over!!!'        “print infobox”输出其中一门语言actionscript的infobox消息盒部分源代码如下:
actionscript
发行时间 1998年
实现者
启发语言

        5. 爬取消息盒属性-属性值

        爬取格式如下:
       
               
                     
                     
               
       
属性

        其中th表示加粗处理,td和th中可能存在属性如title、id、type等值;同时之间的内容可能存在ag凯发k8国际或或
等值,都需要处理。下面先讲解正则表达式获取td值的例子:
        参考:http://bbs.csdn.net/topics/390353859?page=1
序列号dein3-39cd3-2093j3 日期2013年1月22日 售价392.70 元 说明仅限5用户使用
        python代码如下:
s = ''' ....
''' #对应上面html res = r'(.*?)(.*?)' 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用户使用         如果包含该属性则正则表达式为r'(.*?)';同样如果不一定是id属性开头,则可以使用正则表达式r'(.*?)'。
        最终代码如下:
# 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-zif url.find('wiki')>=0 or url.find('index.php')>=0: fileurl.write(url '\n')#print urlnum=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:#下载静态htmlwikiurl='http://zh.wikipedia.org' str(url)print wikiurllanguage = urllib.urlopen(wikiurl).read()name=str(j) ' language.html'#注意 需要创建一个country的文件夹 否则总报错no such file or directoryopen(r'language/' name,'w ').write(language) #写方式打开 没有即创建#获取title信息title_pat=r'(?<=).*?(?=)'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的内容#标准方法是通过匹配
确认其内容,找与它最近的一个结束符号#但此处分析源码后取巧

实现start=language.find(r'

' title[:middle-1]) #减去1个空格infobox=language[start:end]#print infobox#第五步 获取table中属性-属性值if "infobox vevent" in language: #防止无infobox输出多余换行#获取table中tr值res_tr = r'(.*?)'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''m_th = re.findall(res_th,line,re.s|re.m)for mm in m_th:#如果获取加粗的th中含超链接则处理if "href" in mm:restr = r''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 foundprint unicode(mm,'utf-8') #unicode防止乱info.write(mm '\n')#获取表格第二列td 属性值res_td = r''m_td = re.findall(res_td,line,re.s|re.m)for nn in m_td:if "href" in nn:#处理超链接res_value = r''m_value = re.findall(res_value,nn,re.s|re.m) #m_td会出现typeerror: expected string or bufferfor 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 1time.sleep(1)if j==40:break;else:print 'error url!!!' else:print 'download over!!!'        输出结果是自定义爬取多少门语言,其中ada编程语言如下图所示:
        最初我采用的是如下方法,维基百科需要中文繁体,需要人工标注分析html再爬取两个尖括号(>...<)之间的内容:
#启发语言 start=infobox.find(r'啟發語言') end=infobox.find(r'
',start) print infobox[start:end] info.write(infobox[start:end] '\n')         当然代码中还存在很多小问题,比如爬取的信息中含

ag凯发k8国际为你收集整理的[python学习] 简单爬取维基百科程序语言消息盒的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得ag凯发k8国际网站内容还不错,欢迎将ag凯发k8国际推荐给好友。

  • 上一篇:
  • 下一篇:
(.*?)(.*?)
网站地图