python实现网络爬虫、蜘蛛

python实现网络爬虫、蜘蛛

ID:21961067

大小:657.00 KB

页数:115页

时间:2018-10-25

上传者:xinshengwencai
python实现网络爬虫、蜘蛛_第1页
python实现网络爬虫、蜘蛛_第2页
python实现网络爬虫、蜘蛛_第3页
python实现网络爬虫、蜘蛛_第4页
python实现网络爬虫、蜘蛛_第5页
资源描述:

《python实现网络爬虫、蜘蛛》由会员上传分享,免费在线阅读,更多相关内容在教育资源-天天文库

python中如何提取网页正文啊谢谢importurllib.request url="http://google.cn/" response=urllib.request.urlopen(url) page=response.read() python提取网页中的文本1.importos,sys,datetime   2.importhttplib,urllib,re   3.fromsgmllibimportSGMLParser   4.  5.importtypes   6.  7.classHtml2txt(SGMLParser):   8.    defreset(self):   9.        self.text=''  10.        self.inbody=True  11.        SGMLParser.reset(self)   12.    defhandle_data(self,text):   13.        ifself.inbody:   14.            self.text+=text   15.  16.    defstart_head(self,text):   17.        self.inbody=False  18.    defend_head(self):   19.        self.inbody=True  20.  21.  22.if__name__=="__main__":   23.    parser=Html2txt()   24.    parser.feed(urllib.urlopen("http://icode.csdn.net").read())   25.    parser.close()   26.    printparser.text.strip()  python下载网页importhttplib  conn=httplib.HTTPConnection("www.baidu.com")conn.request("GET","/index.html")r1=conn.getresponse()printr1.status,r1.reason data=r1.read()printdataconn.close用python下载网页,超级简单!fromurllibimporturlopenwebdata=urlopen("").read()printwebdata深入python里面有python 下载网页内容,用python的pycurl模块实现1.用python下载网页内容还是很不错的,之前是使用urllib模块实验的,但听说有pycurl这个模块,而且比urllib好,所以尝试下,废话不说,以下是代码2.3.4.#!/usr/bin/envpython5.#-*-coding:utf-8-*-6.importStringIO7.importpycurl8.9.defwritefile(fstr,xfilename): f=open(xfilename,'w') f.write(fstr) f.close10.1.html=StringIO.StringIO() 1.c=pycurl.Curl()2.myurl='http://www.ppgchenshan.com'3. 4.c.setopt(pycurl.URL,myurl)5. 6.#写的回调7.c.setopt(pycurl.WRITEFUNCTION,html.write)8. 9.c.setopt(pycurl.FOLLOWLOCATION,1)10. 11.#最大重定向次数,可以预防重定向陷阱12.c.setopt(pycurl.MAXREDIRS,5)13. 14.#连接超时设置15.c.setopt(pycurl.CONNECTTIMEOUT,60)16.c.setopt(pycurl.TIMEOUT,300)17. 18.#模拟浏览器19.c.setopt(pycurl.USERAGENT,"Mozilla/4.0(compatible;MSIE6.0;WindowsNT5.1;SV1;.NETCLR1.1.4322)")20. 21. 22. 23.#访问,阻塞到访问结束24.c.perform()25. 26.#打印出200(HTTP状态码,可以不需要)27.printc.getinfo(pycurl.HTTP_CODE)28.  1.#输出网页的内容2.printhtml.getvalue()3.#保存成down.txt文件4.writefile(html.getvalue(),"down.txt")python的pycurl模块的安装可以到http://pycurl.sourceforge.net/download/这里去找.不同系统使用不同版本,自己看看总结下,Python下载网页的几种方法1fd=urllib2.urlopen(url_link)data=fd.read()这是最简洁的一种,当然也是Get的方法2通过GET的方法defGetHtmlSource(url):try:htmSource=''req=urllib2.Request(url)fd=urllib2.urlopen(req,"")while1:data=fd.read(1024)ifnotlen(data):breakhtmSource+=datafd.close() delfddelreqhtmSource=htmSource.decode('cp936')htmSource=formatStr(htmSource)returnhtmSourceexceptsocket.error,err:str_err="%s"%errreturn""3通过GET的方法defGetHtmlSource_Get(htmurl):htmSource=""try:urlx=httplib.urlsplit(htmurl)conn=httplib.HTTPConnection(urlx.netloc)conn.connect()conn.putrequest("GET",htmurl,None)conn.putheader("Content-Length",0)conn.putheader("Connection","close")conn.endheaders()res=conn.getresponse()htmSource=res.read()exceptException(),err:trackback.print_exec()conn.close()returnhtmSource 通过POST的方法defGetHtmlSource_Post(getString):htmSource=""try:url=httplib.urlsplit("http://app.sipo.gov.cn:8080")conn=httplib.HTTPConnection(url.netloc)conn.connect()conn.putrequest("POST","/sipo/zljs/hyjs-jieguo.jsp")conn.putheader("Content-Length",len(getString))conn.putheader("Content-Type","application/x-www-form-urlencoded")conn.putheader("Connection","Keep-Alive")conn.endheaders()conn.send(getString)f=conn.getresponse()ifnotf:raisesocket.error,"timedout"htmSource=f.read()f.close()conn.close()returnhtmSourceexceptException(),err:trackback.print_exec()conn.close()returnhtmSource本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/sding/archive/2010/04/29/5538065.aspxDjango+python+BeautifulSoup组合的垂直搜索爬虫 使用python+BeautifulSoup完成爬虫抓取特定数据的工作,并使用Django搭建一个管理平台,用来协调抓取工作。因为自己很喜欢Djangoadmin后台,所以这次用这个后台对抓取到的链接进行管理,使我的爬虫可以应对各种后期的需求。比如分时段抓取,定期的对已经抓取的地址重新抓取。数据库是用python自带的sqlite3,所以很方便。这几天正好在做一个电影推荐系统,需要些电影数据。本文的例子是对豆瓣电影抓取特定的数据。第一步:建立Django模型模仿nutch的爬虫思路,这里简化了。每次抓取任务开始先从数据库里找到未保存的(is_save=False)的链接,放到抓取链表里。你也可以根据自己的需求去过滤链接。python代码:viewplaincopytoclipboardprint?01.classCrawl_URL(models.Model):02.url=models.URLField('抓取地址',max_length=100,unique=True)03.weight=models.SmallIntegerField('抓取深度',default=0)#抓取深度起始104.is_save=models.BooleanField('是否已保存',default=False)#05.date=models.DateTimeField('保存时间',auto_now_add=True,blank=True,null=True)06.def__unicode__(self):07.returnself.urlclassCrawl_URL(models.Model):url=models.URLField('抓取地址',max_length=100,unique=True)weight=models.SmallIntegerField('抓取深度',default=0)#抓取深度起始1is_save=models.BooleanField('是否已保存',default=False)#date=models.DateTimeField('保存时间',auto_now_add=True,blank=True,null=True)def__unicode__(self):returnself.url然后生成相应的表。还需要一个admin管理后台viewplaincopytoclipboardprint?01.classCrawl_URLAdmin(admin.ModelAdmin):02.list_display=('url','weight','is_save','date',) 03.ordering=('-id',)04.list_filter=('is_save','weight','date',)05.fields=('url','weight','is_save',)06.admin.site.register(Crawl_URL,Crawl_URLAdmin)classCrawl_URLAdmin(admin.ModelAdmin):list_display=('url','weight','is_save','date',)ordering=('-id',)list_filter=('is_save','weight','date',)fields=('url','weight','is_save',)admin.site.register(Crawl_URL,Crawl_URLAdmin)第二步,编写爬虫代码爬虫是单线程,并且每次抓取后都有相应的暂定,豆瓣网会禁止一定强度抓取的爬虫爬虫根据深度来控制,每次都是先生成链接,然后抓取,并解析出更多的链接,最后将抓取过的链接is_save=true,并把新链接存入数据库中。每次一个深度抓取完后都需要花比较长的时候把链接导入数据库。因为需要判断链接是否已存入数据库。这个只对满足正则表达式http://movie.douban.com/subject/(d+)/的地址进行数据解析。并且直接忽略掉不是电影模块的链接。第一次抓取需要在后台加个链接,比如http://movie.douban.com/chart,这是个排行榜的页面,电影比较受欢迎。python代码:#这段代码不能格式化发#coding=UTF-8importurllib2fromBeautifulSoupimport*fromurlparseimporturljoinfrompysqlite2importdbapi2assqlitefrommovie.modelsimport*fromdjango.contrib.auth.modelsimportUserfromtimeimportsleepimage_path='C:/Users/soul/djcodetest/picture/'user=User.objects.get(id=1)defcrawl(depth=10):foriinrange(1,depth): print'开始抓取for%d....'%ipages=Crawl_URL.objects.filter(is_save=False)newurls={}forcrawl_pageinpages:page=crawl_page.urltry:c=urllib2.urlopen(page)except:continuetry:#解析元数据和urlsoup=BeautifulSoup(c.read())#解析电影页面ifre.search(r'^http://movie.douban.com/subject/(d+)/$',page):read_html(soup)#解析出有效的链接,放入newurlslinks=soup('a')forlinkinlinks:if'href'indict(link.attrs):url=urljoin(page,link['href'])ifurl.find("'")!=-1:continueiflen(url)>60:continueurl=url.split('#')[0]#removielocationportionifre.search(r'^http://movie.douban.com',url):newurls[url]=crawl_page.weight+1#连接有效。存入字典中try:print'addurl:'except:passexceptException.args:try:print"Couldnotparse:%s"%argsexcept:pass#newurls存入数据库is_save=Falseweight=icrawl_page.is_save=Truecrawl_page.save()#休眠2.5秒sleep(2.5)save_url(newurls)#保存url,放到数据库里defsave_url(newurls):for(url,weight)innewurls.items():url=Crawl_URL(url=url,weight=weight) try:url.save()except:try:print'url重复:'except:passreturnTrue第三步,用BeautifulSoup解析页面抽取出电影标题,图片,剧情介绍,主演,标签,地区。关于BeautifulSoup的使用可以看这里BeautifulSoup技术文档viewplaincopytoclipboardprint?01.#抓取数据02.defread_html(soup):03.#解析出标题04.html_title=soup.html.head.title.string05.title=html_title[:len(html_title)-5]06.#解析出电影介绍07.try:08.intro=soup.find('span',attrs={'class':'allhidden'}).text09.except:10.try:11.node=soup.find('div',attrs={'class':'blank20'}).previousSibling12.intro=node.contents[0]+node.contents[2]13.except:14.try:15.contents=soup.find('div',attrs={'class':'blank20'}).previousSibling.previousSibling.text16.intro=contents[:len(contents)-22]17.except:18.intro=u'暂无'19.20.#取得图片21.html_image=soup('a',href=re.compile('douban.com/lpic'))[0]['href']22.data=urllib2.urlopen(html_image).read()23.image='201003/'+html_image[html_image.rfind('/')+1:]24.f=file(image_path+image,'wb')25.f.write(data)26.f.close()27.28.29.#解析出地区30.try:31.soup_obmo=soup.find('div',attrs={'class':'obmo'}).findAll('span')32.html_area=soup_obmo[0].nextSibling.split('/')33.area=html_area[0].lstrip()34.except:35.area=''36.37.#time=soup_obmo[1].nextSibling.split('')[1]38.#time=time.strptime(html_time,'%Y-%m-%d')39.40.#生成电影对象41.new_movie=Movie(title=title,intro=intro,area=area,version='暂无',upload_user=user,image=image)42.new_movie.save()43.try:44.actors=soup.find('div',attrs={'id':'info'}).findAll('span')[5].nextSibling.nextSibling.string.split('')[0]45.actors_list=Actor.objects.filter(name=actors)46.iflen(actors_list)==1:47.actor=actors_list[0]48.new_movie.actors.add(actor)49.else:50.actor=Actor(name=actors)51.actor.save()52.new_movie.actors.add(actor)53.except:54.pass55.56.#tag57.tags=soup.find('div',attrs={'class':'blank20'}).findAll('a')58.fortag_htmlintags:59.tag_str=tag_html.string60.iflen(tag_str)>4:61.continue62.tag_list=Tag.objects.filter(name=tag_str)63.iflen(tag_list)==1:64.tag=tag_list[0]65. 66.new_movie.tags.add(tag)67.else:68.tag=Tag(name=tag_str)69.tag.save()70.new_movie.tags.add(tag)71.#try:72.73.#exceptException.args:74.#print"Couldnotdownload:%s"%args75.printr'downloadsuccess'76.#抓取数据defread_html(soup):#解析出标题html_title=soup.html.head.title.stringtitle=html_title[:len(html_title)-5]#解析出电影介绍try:intro=soup.find('span',attrs={'class':'allhidden'}).textexcept:try:node=soup.find('div',attrs={'class':'blank20'}).previousSiblingintro=node.contents[0]+node.contents[2]except:try:contents=soup.find('div',attrs={'class':'blank20'}).previousSibling.previousSibling.textintro=contents[:len(contents)-22]except:intro=u'暂无'#取得图片html_image=soup('a',href=re.compile('douban.com/lpic'))[0]['href']data=urllib2.urlopen(html_image).read()image='201003/'+html_image[html_image.rfind('/')+1:]f=file(image_path+image,'wb')f.write(data)f.close()#解析出地区try:soup_obmo=soup.find('div',attrs={'class':'obmo'}).findAll('span')html_area=soup_obmo[0].nextSibling.split('/')area=html_area[0].lstrip()except:area=''#time=soup_obmo[1].nextSibling.split('')[1]#time=time.strptime(html_time,'%Y-%m-%d')#生成电影对象new_movie= Movie(title=title,intro=intro,area=area,version='暂无',upload_user=user,image=image)new_movie.save()try:actors=soup.find('div',attrs={'id':'info'}).findAll('span')[5].nextSibling.nextSibling.string.split('')[0]actors_list=Actor.objects.filter(name=actors)iflen(actors_list)==1:actor=actors_list[0]new_movie.actors.add(actor)else:actor=Actor(name=actors)actor.save()new_movie.actors.add(actor)except:pass#tagtags=soup.find('div',attrs={'class':'blank20'}).findAll('a')fortag_htmlintags:tag_str=tag_html.stringiflen(tag_str)>4:continuetag_list=Tag.objects.filter(name=tag_str)iflen(tag_list)==1:tag=tag_list[0]new_movie.tags.add(tag)else:tag=Tag(name=tag_str)tag.save()new_movie.tags.add(tag)#try:#exceptException.args:#print"Couldnotdownload:%s"%argsprintr'downloadsuccess'豆瓣的电影页面并不是很对称,所以有时候抓取的结果可能会有点出入本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/Java2King/archive/2010/03/15/5378951.aspx 爬Google的查询页最近没有没有GoogleAPIkey了,因此只能自己将查询对应的URL准备好,然后通过脚本将该链接对应的网页爬下来。我们假定,我们要爬这样一个页面:http://www.google.com/search?q=IBM我们可以直接在浏览器输入上面的URL,可以看到,是Google对应IBM这个查询的返回页。我们现在的目的是通过python程序把这个返回页download下来,存在本地,为后面的工作准备数据。一下就是我的代码:importurllib2,urlparse,gzipfromStringIOimportStringIOUSER_AGENT='Mozilla/4.0(compatible;MSIE6.0;WindowsNT5.1;SV1;.NETCLR2.0.50727;CIBA;InfoPath.2;360SE)'classSmartRedirectHandler(urllib2.HTTPRedirectHandler):defhttp_error_301(self,req,fp,code,msg,headers):result=urllib2.HTTPRedirectHandler.http_error_301(self,req,fp,code,msg,headers)result.status=codereturnresultdefhttp_error_302(self,req,fp,code,msg,headers):result=urllib2.HTTPRedirectHandler.http_error_302(self,req,fp,code,msg,headers)result.status=codereturnresultclassDefaultErrorHandler(urllib2.HTTPDefaultErrorHandler):defhttp_error_default(self,req,fp,code,msg,headers):result=urllib2.HTTPError(req.get_full_url(),code,msg,headers,fp)result.status=codereturnresultdefopenAnything(source,etag=None,lastmodified=None,agent=USER_AGENT):ifhasattr(source,'read'):returnsourceifsource=='-':returnsys.stdin ifurlparse.urlparse(source)[0]=='http':request=urllib2.Request(source)request.add_header('USER-AGENT',agent)request.add_header('Cookie','PREF=ID=5e8d1d15fe369be8:U=95d9eb627acc6c79:LD=en:NW=1:CR=2:TM=1270616770:LM=1270616914:S=FAiBW5rEW2azKJXk;NID=33=rXimIAwO_TvEyFlE4lBRkxr1x3TTVh36maim2Cn0gk3b3SAbtn79qkAtgIli18d382TnTCFMOXjzgqxQFCEWLHEbnyf-MtVwfa4-pYmXSMkUMPYqDi61ZmmqyPcBbwzP')ifetag:request.add_header('If-None-Match',etag)iflastmodified:request.add_header('If-Modified-Since',lastmodified)#request.add_header('Accept-encoding','gzip')#request.add_header('Connection','Keep-Alive')opener=urllib2.build_opener(SmartRedirectHandler(),DefaultErrorHandler())returnopener.open(request)try:returnopen(source)except(IOError,OSError):passreturnStringIO(str(sources))deffetch(source,etag=None,last_modified=None,agent=USER_AGENT):result={}f=openAnything(source,etag,last_modified,agent)result['data']=f.read()ifhasattr(f,'headers'):result['etag']=f.headers.get('ETag')result['lastmodified']=f.headers.get('Last-Modified')iff.headers.get('content-encoding','')=='gzip':result['date']=gzip.GzipFile(fileobj=StringIO(result['data'])).read()ifhasattr(f,'url'):result['url']=f.urlresult['status']=200ifhasattr(f,'status'):result['status']=f.statusf.close()returnresultif__name__=='__main__':result=fetch("http://www.google.com/search?q=IBM") printresult['data']printresult['url']printresult['status']要注意一下几点:1、要加User-agent,否则GOOGLE会返回403的forbidden信息,因为Python默认的User-agent是python........2、如果不想被重定向到Google中国,哦,NO,是Google香港,那么要记得在自己的cookie中找到对应的cookie加上去3、这种东西要多抓包,一个字节一个字节的比对,要相信,浏览器也是程序写的,浏览器能做到的程序也能做到本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/caiyichaobupt/archive/2010/04/08/5459497.aspx下载糗事百科的内容_python版1.#coding:utf-82.3.importurllib.request4.importxml.dom.minidom5.importsqlite36.importthreading7.importtime8.9.classlogger(object):10.deflog(self,*msg):11.foriinmsg:12.print(i)13.14.Log=logger()15.Log.log('测试下')16.17.classdownloader(object):18.19.def__init__(self,url):20.self.url=url21.22.defdownload(self):23.Log.log('开始下载',self.url)24.try:25.content=urllib.request.urlopen(self.url).read()26.#req=urllib.request.Request(url)27.#response=urllib.request.urlopen(req)28.#content=response.read()29.Log.log('下载完毕')30.return(content) 31.except:32.Log.log('下载出错')33.return(None)34.35.36.classparser(object):37.38.def__init__(self,content):39.#获得根节点40.self.html=xml.dom.minidom.parseString(content)41.42.defparse(self):43.Log.log('开始提取数据')44.contents={'content':'','url':[]}45.#获得div节点46.divs=self.html.getElementsByTagName('div')47.#获得content节点48.fordivindivs:49.ifdiv.hasAttribute('class')and50.div.getAttribute('class')=='content':51.#获得糗事百科的内容52.textNode=div.childNodes[0]53.qContent=textNode.data54.#数据填充55.contents['content']=qContent56.57.#获得上一糗事、下一糗事节点58.spans=self.html.getElementsByTagName('span')59.forspaninspans:60.pspan=span.parentNode61.ifpspan.tagName=='a':62.#pspan为对应的链接,此时需要将对应的地址加入数据库63.url=pspan.getAttribute('href')64.qid=url[10:][:-4]65.#数据填充66.contents['url'].append(qid)67.Log.log('提取数据完毕')68.return(contents)69.70.defdownloadPage(qid,db):71.url='http://www.qiushibaike.com/articles/'+str(qid)+'.htm'72.content=downloader(url).download()73.ifcontent:74.contents=parser(content).parse()75.ifcontents['content']:76.db.updateContent(qid,contents['content'])77.foriincontents['url']:78.db.addQID(i)79.iflen(contents['url'])==2:80.db.updateStatus(qid,2)81.82.#下载池,表示同时允许下载的链接个数83.classdownloaderPool(object): 84.def__init__(self,maxLength=15):85.self.downloaders=[None]*maxLength86.self.downloadList=[]87.self.db=None88.89.defsetDownloadList(self,downloadList):90.self.downloadList=list(set(self.downloadList+downloadList))91.92.defsetdb(self,db):93.self.db=db94.95.defdaemon(self):96.#每隔一秒查询线程的状态,为非活动线程则设置为None97.Log.log('设置守护进程')98.forindex,downloaderinenumerate(self.downloaders):99.ifdownloader:100.ifnotdownloader.isAlive():101.Log.log('将下载器置空',index)102.self.downloaders[index]=None103.104.#检查线程池状态105.forindex,downloaderinenumerate(self.downloaders):106.ifnotdownloader:107.qid=self.getQID()108.ifqid:109.#创建线程110.t=threading.Thread(target=downloadPage,args=(qid,self.db))111.self.downloaders[index]=t112.t.start()113.t.join()114.Log.log('设置下载器',index)115.#间隔一秒执行一次116.time.sleep(1)117.118.defgetQID(self):119.try:120.tmp=self.downloadList[0]121.delself.downloadList[0]122.return(tmp)123.except:124.return(None)125.126.defbeginDownload(self):127.#创建守护线程128.daemon=threading.Thread(target=self.daemon)129.daemon.setDaemon(True)130.daemon.start()131.daemon.join()132. 133.defgetDownloader(self):134.forindex,downloaderinenumerate(self.downloaders):135.ifnotdownloader:136.return(index)137.return(None)138.139.140.ADD_Q_ID='insertintoqiushibaike(id,success)values(?,?)'141.UPDATE_Q_CONTENT='updateqiushibaikesetcontent=?whereid=?'142.UPDATE_Q_STATUS='updateqiushibaikesetsuccess=?whereid=?'143.Q_LIST='selectidfromqiushibaikewheresuccess=?'144.Q_LIST_BY_ID='selectcount(*)fromqiushibaikewhereid=?'145.classdbConnect(object):146."""147.createtableqiushibaike(148.id,Integer149.content,Varchar150.success,Interger151.)152.#id表示糗事的ID153.#content表示糗事的内容154.#success表示是否下载成功,当该糗事内容下载完成,且获得上一页、下一页ID时表示下载完成155.1表示未完成156.2表示完成157."""158.def__init__(self,dbpath='db.sqlite'):159.self.dbpath=dbpath160.161.defaddQID(self,qid):162.Log.log('插入糗事百科',qid)163.#获得连接164.cn=sqlite3.connect(self.dbpath)165.c=cn.cursor()166.167.try:168.#添加内容并提交169.c.execute(ADD_Q_ID,(qid,1))170.cn.commit()171.except:172.Log.log('添加ID出错',qid)173.174.#关闭连接175.c.close()176.177.cn.close()178.Log.log('插入成功')179.180.defupdateContent(self,qid,content):181.Log.log('更新糗事百科',qid,content) 182.#获得连接183.cn=sqlite3.connect(self.dbpath)184.c=cn.cursor()185.#添加内容并提交186.c.execute(UPDATE_Q_CONTENT,(content,qid))187.cn.commit()188.#关闭连接189.c.close()190.cn.close()191.Log.log('更新成功')192.193.defupdateStatus(self,qid,flag):194.Log.log('更新状态',qid,flag)195.#获得连接196.cn=sqlite3.connect(self.dbpath)197.c=cn.cursor()198.#添加内容并提交199.c.execute(UPDATE_Q_STATUS,(flag,qid))200.cn.commit()201.#关闭连接202.c.close()203.cn.close()204.Log.log('更新状态成功')205.206.defgetList(self,unDonloaded=1):207.Log.log('获得列表')208.l=[]209.#获得连接210.cn=sqlite3.connect(self.dbpath)211.c=cn.cursor()212.#获得数据213.c.execute(Q_LIST,(unDonloaded,))214.rows=c.fetchall()215.216.foriinrows:217.l.append(i[0])218.#关闭连接219.c.close()220.cn.close()221.222.Log.log('获得列表成功')223.return(l)224.225.classsingleDownloader(object):226.def__init__(self):227.self.downloadList=[]228.229.defsetdb(self,db):230.self.db=db231.232.defsetDownloadList(self,downloadList):233.self.downloadList=list(set(self.downloadList+downloadList))234.235.defbeginDownload(self): 236.foriinself.downloadList:237.downloadPage(i,self.db)238.239.defmain():240.db=dbConnect('db.sqlite')241.#dp=downloaderPool()242.#dp.setdb(db)243.sp=singleDownloader()244.sp.setdb(db)245.246.dp=sp247.248.unDownloadedList=db.getList()249.#当还有未下载的糗事时就要继续下载250.while(len(unDownloadedList)):251.#使用该列表填充下载池252.dp.setDownloadList(unDownloadedList)253.254.dp.beginDownload()255.256.time.sleep(1)257.#重置参数258.unDownloadedList=db.getList()259.260.if__name__=='__main__':261.main()代码是没问题的,可以正常运行,但是希望做到以下2方面:1、多线程下载2、代码分离度更高,跟面向对象各位看家有什么好想法,贴出来看看。本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/jj_liuxin/archive/2008/12/08/3466701.aspx用python把xml和xsl转换为html前些天用python处理xml的转换的一个小程序,用来把xml,xsl转换成html。用的libxml2,所以还要先安装了libxml2模块才能使用。#-*-coding:mbcs-*-#!/usr/bin/pythonimportlibxml2,libxsltclasscompoundXML:def__init__(self):self._result=None self._xsl=Noneself._xml=Nonedefdo(self,xml_file_name,xsl_file_name):self._xml=libxml2.parseFile(xml_file_name)ifself._xml==None:return0styledoc=libxml2.parseFile(xsl_file_name)ifstyledoc==None:return0self._xsl=libxslt.parseStylesheetDoc(styledoc)ifself._xsl==None:return0self._result=self._xsl.applyStylesheet(self._xml,None)defget_xml_doc(self):returnself._resultdefget_translated(self):returnself._result.serialize('UTF-8')defsave_translated(self,file_name):self._xsl.saveResultToFilename(file_name,self._result,0)defrelease(self):'''thisfunctionmustbecalledintheend.'''self._xsl.freeStylesheet()self._xml.freeDoc()self._result.freeDoc()self._xsl=Noneself._xml=Noneself._result=Noneif__name__=='__main__':test=compoundXML()test.do('test/testxmlutil.xml','test/testxmlutil.xsl')printtest.get_translated() test.save_translated('test/testxmlutil.htm')test.release()本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/zhaoweikid/archive/2004/08/14/74837.aspx用python下载网页,超级简单!fromurllibimporturlopenwebdata=urlopen("http://www.pythonid.com").read()printwebdata够简单吧,哈哈。我来补充点,你那只能说是查看网页,怎能说是下载呢,总得如存吧importurllibwebfile=urllib.urlopen("http://www.insenz.com").read()fp=file('rhf.html','a+')#fp=open('rhf.html','a+')fp.write(webfile)fp.close()哦,我没有试www.insenz.com,我试的http://www.pythonid.com最简单的下载网页的方法只有2句:fromurllibimport urlretrieveurlretrieve('http://www.python.org','f:\python_webpage.html')用python下载网页,超级简单!查看fromurllibimporturlopenwebdata=urlopen("http://www.pythonid.com").read()printwebdata---------------下载并保存importurllibwebfile=urllib.urlopen("http://www.insenz.com").read()fp=file('rhf.html','a+')#fp=open('rhf.html','a+')fp.write(webfile)fp.close()------------------下载南方周末最新网页并保存成一个txt文件列表里有个牛人做的。啄木鸟社区收录了.地址:http://wiki.woodpecker.org.cn/moin/MicroProj/2007-07-06#downhtmlfromzmandsavehtmltotxt#  -*-coding:utf-8-*-importhtmllib,formatter,urllib,rewebsite='http://www.nanfangdaily.com.cn/zm/'f=urllib.urlopen(website)html=f.read().lower()i=html.find('url=')j=html.find('/',i+4)date=html[i+4:j]website+=datef=urllib.urlopen(website)p=htmllib.HTMLParser(formatter.NullFormatter())p.feed(f.read())p.close()seen=set()forurlinp.anchorlist:ifurl[-3::]=='asp':  ifurlinseen:continue   seen.add(url)urls=list(seen)k=len(urls)doc=open(u'南方周末'.encode('gb18030')+date+'.txt','a')forl,urlinenumerate(urls):f=urllib.urlopen(website+url[1:])html=f.read()i=html.find('#ff0000')i=html.find('>',i+7)j=html.find('<',i+1)doc.write(html[i+1:j])i=html.find('content01',j+1)i=html.find('>',i+9)j=html.find(']*>',re.IGNORECASE)doc.write(reobj.sub(' ',content)+' ------------ ')printl+1,'-->',kdoc.close()printu'下载结束'把百度空间的文章下载为html/*作者:youstarhttp://www.youstar.org.ru转载注明原创*/0x1  本文借鉴网上的代码加以修改实现了一个可以把百度空间的文章下载为html的功能,相对而言还有很多功能需要添加。编程使用的语言是python,越来越喜欢这脚本了,感觉在处理很多事情上很方便,其中调用一些lib和函数,看代码的时候也学到了一些函数的使用。0x2#!/usr/bin/envpython#coding=utf-8importurllib2importreimportsysimportospattern=""reg_tail=""username=""defdownURL(url,filename):   print"Download%s,saveas%s"%(url, filename)   try:       fp=urllib2.urlopen(url)   except:       print"downloadexception"       return0   paths=os.getcwd()+username+'/'+filename   op=open(paths,"wb")   while1:       s=fp.read()       ifnots:           break       op.write(s)   fp.close()   op.close()   return1defgetURL(url):   print"Parsing%s"%url   try:       fp=urllib2.urlopen(url)       contents=fp.readlines()   except:       print"exception"       return[]   item_list=[]   forsincontents:       urls=pattern.findall(s)       ifurls:           item_list.extend(urls)       fp.close()   returnitem_listdefCreateDirectory():   ifnotos.path.exists(os.getcwd()+username):        os.mkdir(os.getcwd()+username)        print'step2:CreateDirectorySuccess!'   else:        print'step2:Directoryhasexisted!'defreptile(base_url):   """   Downloadallarticlesfrombase_url.   Arguments:   -`base_url`:Urlofwebsite.   """   page_list= []   base_page=base_url.rstrip("/")+"/blog/index/"   sign_tail=u"尾页"   tail=""   total_page=10   globalusername   print'step3:Numberofindex'   try:       fp=urllib2.urlopen(base_page+"0")   except:       print"%s:Notsuchurl"%page       printsys.exc_info()   else:       forsinfp.readlines():           ifsign_tailins.decode("gbk"):               tail=s.decode("gbk")               break       fp.close()   iftail:       pos=tail.rfind(u"尾页")       total_page=int(tail[:pos-3].split("/")[-1])   output_list=[]   foridxinrange(total_page+1):       item_page="%s%d"%(base_page,idx)       item_list=getURL(item_page)       ifitem_list:           output_list.extend(item_list)      print'step4:Downpages!'   item_list=list(set(output_list))   foriteminitem_list:       down_url=item.replace("/%s"%username,                               "http://hi.baidu.com/%s"%username)       local_file=down_url.split("/")[-1]       ret=downURL(down_url,local_file)   print"step5:Total:%darticles."%(len(item_list))   print"Congratulations"   passif__name__=='__main__':   iflen(sys.argv)!=2:       print"Usage:%surlofbaiduspace"%sys.argv[0]       print"Suchas:%shttp://hi.baidu.com/Username "       sys.exit(1)   base_url=sys.argv[1]   ifnotbase_url.startswith("http://hi.baidu.com/"):       print"WrongTypeofURL??","ItworksonBaiduSpaceonly."       sys.exit(1)username=base_url.rstrip("/").split("/")[-1]   print('step1:'+username)   CreateDirectory()   reg_tail=re.compile(u"%s.*?尾页"%username)   pattern=re.compile("/%s/blog/item/.*?.html"%username)   reptile(base_url)0x3  实现界面0x4  link:  http://hi.baidu.com/yangyingchao/blog/item/25d74f1ed9ec11f91ad5767d.html  http://zh-cn.w3support.net/index.php?db=so&id=273192用Python进行网页分析实现批量下载(finalversion)转自:http://www.builder.com.cn/2008/0517/867087.shtmlstart.bat       //makethedirforfilesandruntheproject        mkdirfiles       pythonCustomParser.pyCustomParser.pyfromsgmllibimportSGMLParserfromstringimportfind,replace,rjustfromthreadingimportThreadimporturllib__author__="ChenPeng(peng.ch@hotmail.com)"__version__="$Revision:1.0$"__date__="$Date:2006/03/03$"__copyright__="Copyright(c)2006ChenPeng"__license__="Python"__all__=["Gif_163_Parser"]classPDownloadThread(Thread):   """   Downloadthefilesinthedictandsavethemtolocalfileswiththegivenname   """   def__init__(self,DictList,i):       Thread.__init__(self)       self.DictList=DictList       self.pageno=str(i);     defrun(self):           forkinself.DictList.keys():           try:             print'Download'+self.DictList[k]+'......'             uFile=urllib.urlretrieve(self.DictList[k],'.files'+k+'.'+self.DictList[k].split('.')[self.DictList[k].split('.').__len__()-1])           except:              logfile=open('error.log','a')              logfile.write(self.pageno+''+self.DictList[k]+'  '+k+'n')              logfile.close()           print'Savetofile'+k        classGif_163_Parser(SGMLParser):  """   任务:下载163彩图   原理:http://mms.163.com/new_web/cm_lv2_pic.jsp?catID=&ord=dDate&page=2&type=1&key=       从1到415页(共6637)分析得到如下路径:“/fgwx/hhsj/1_060302175613_186/128x128.gif”  eg:       下载路径:http://mmsimg.163.com/new_web/loaditem.jsp/type=1/path=/fgwx/llfj/1_060302175612_995/176x176.gif  """  defreset(self):                                    SGMLParser.reset(self)       self.headURL='http://mmsimg.163.com/new_web/loaditem.jsp/type=1/path='       self.SubURL=[]       self.Links={}           defstart_script(self,attrs):       #self.SubURL.extend(['%s="%s"'%(key,value)forkey,valueinattrs])       pass  defend_script(self):       pass    defhandle_data(self,text):       iffind(text,'showPic')!=-1:          self.Links[replace(text.split('n')[1],'xc3xfbxd7xd6:','')]=self.headURL+replace(text.split(',')[2],''','');             defExecute(self):        foriinrange(1,415):          self.Links.clear;          try:              usock=urllib.urlopen("http://mms.163.com/new_web/cm_lv2_pic.jsp?catID=&ord=dDate&page="+str(i)+"&type=1&key=" )              self.feed(usock.read())              usock.close()                                  TestThread=PDownloadThread(self.Links,i)              TestThread.start()                              self.close()              exceptIOError:              pass          #print(["%s=%sn"%(k,self.Links[k])forkinself.Links.keys()])       #printself.Linksif__name__=='__main__':   #Gif_163_Parser().Execute();    testtask=Gif_163_Parser()    testtask.Execute()  python下载天涯图片http://octoberken.blogbus.com/logs/46055962.html高喊学python好多天。。。就是没作出过什么东西。前几天看见同事用java写了个下载天涯图片的程序,于是也用python写了一个练练手。。 #-*-coding:gbk-*-'''Createdon2009-9-7@author:Ken'''import urllibimporturllib2importrandomimportosfromsgmllibimportSGMLParserclassURLLister(SGMLParser):'''获取html中的图片地址url地址,装入list中'''defreset(self):SGMLParser.reset(self)self.img= []self.urls=[]defstart_img(self,attrs):img=[vfork,vinattrsifk=='src']ifimg:self.img.extend(img)defstart_a(self,attrs):href=[vfork,vinattrsifk=='href']ifhref:self.urls.extend(href)defget_docum(url):url=url+'//'sock=urllib.urlopen(url)file=sock.read()sock.close()returnfiledefis_img(url):globalimglenthrequest=urllib2.Request(url)opener=urllib2.build_opener()try:con=opener.open(request)Type=con.headers.dict['content-type'][:5]#判断链接返回的content-type是不是图片。Length=int(con.headers.dict['content-length'])#判断图片大小ifLength>imglenth:returnTypeelse:return0except:print'该图片无法在服务器找到或者图片地址无法识别!'printurldefget_file_name(ospath,imgname):name='P'+str(random.randint(10000000,99999999))filepath="%s%s.%s"%(ospath,name,(imgname.split('.'))[-1])returnfilepath               defget_img(rq):parser=URLLister();   doc=get_docum(rq);   parser.feed(doc);   img=parser.imgparser.close()foriin range(0,len(img)):ifimg[i][0:4]!='http':#处理绝对路径img[i]=rq+img[i]returnimgdefget_url(rq):parser=URLLister();   doc=get_docum(rq);   parser.feed(doc);   urls=parser.urlsparser.close()foriinrange(0,len(urls)):ifurls[i][0:4]!='http':#处理绝对路径urls[i]=rq+urls[i]returnurlsdefdepth(url,dep,ospath):'''三个参数分别是url:需要下载的网站地址dep:需要遍历的深度ospath:图片下载的本地文件夹    '''globalnumifdep<=0:return0else:img=get_img(url)forjinrange(0,len(img)):ifis_img(img[j])=='image':isExist=True;while(isExist):#判断文件是否已经存在filepath=get_file_name(ospath,img[j]);if(notos.path.exists(filepath)):isExist=False;try:urllib.urlretrieve(img[j],filepath)print'已经下载好第%d张图片'%(num+1)num+=1except:print'该图片无法下载或者图片地址无法识别!'printimg[j]else:passurls=get_url(url)iflen(urls)>0:forurlin urls:depth(url,dep-1,ospath)else:return0return1if__name__=='__main__':imglenth=1          #设置需要下载的图片大小。num=0depth('http://www.tudou.com/',2,"E:img\")  print'********************************我爬完了!!******************************************'Python用HTMLParser解析HTML文件HTMLParser是Python自带的模块,使用简单,能够很容易的实现HTML文件的分析。本文主要简单讲一下HTMLParser的用法.使用时需要定义一个从类HTMLParser继承的类,重定义函数:·handle_starttag(tag,attrs)·handle_startendtag(tag,attrs)·handle_endtag(tag)来实现自己需要的功能。tag是的html标签,attrs是(属性,值)元组(tuple)的列表(list).HTMLParser自动将tag和attrs都转为小写。下面给出的例子抽取了html中的所有链接:fromHTMLParserimportHTMLParser classMyHTMLParser(HTMLParser):def__init__(self):HTMLParser.__init__(self)self.links=[] defhandle_starttag(self,tag,attrs):#print"Encounteredthebeginningofa%stag"%tagiftag=="a":iflen(attrs)==0:passelse:for(variable,value)inattrs: ifvariable=="href":self.links.append(value) if__name__=="__main__":html_code="""google.comPythonClubSina"""hp=MyHTMLParser()hp.feed(html_code)hp.close()print(hp.links)输出为:['www.google.com','www.pythonclub.org','www.sina.com.cn']如果想抽取图形链接就要重定义handle_startendtag(tag,attrs)函数从HTML文件中抽取正文的简单方案zz原文地址:http://ai-depot.com/articles/the-easy-way-to-extract-useful-text-from-arbitrary-html/译者导读:这篇文章主要介绍了从不同类型的HTML文件中抽取出真正有用的正文内容的一种有广泛适应性的方法。其功能类似于CSDN近期推出的“剪影”,能够去除页眉、页脚和侧边栏的无关内容,非常实用。其方法简单有效而又出乎意料,看完后难免大呼原来还可以这样!行文简明易懂,虽然应用了人工神经网络这样的算法,但因为FANN良好的封装性,并不要求读者需要懂得ANN。全文示例以Python代码写成,可读性更佳,具有科普气息,值得一读。每个人手中都可能有一大堆讨论不同话题的HTML文档。但你真正感兴趣的内容可能隐藏于广告、布局表格或格式标记以及无数链接当中。甚至更糟的是,你希望那些来自菜单、页眉和页脚的文本能够被过滤掉。如果你不想为每种类型的HTML文件分别编写复杂的抽取程序的话,我这里有一个解决方案。本文讲述如何编写与从大量HTML代码中获取正文内容的简单脚本,这一方法无需知道HTML文件的结构和使用的标签。它能够工作于含有文本内容的所有新闻文章和博客页面…… 你想知道统计学和机器学习在挖掘文本方面能够让你省时省力的原因吗?答案极其简单:使用文本和HTML代码的密度来决定一行文件是否应该输出。(这听起来有点离奇,但它的确有用!)基本的处理工作如下:·一、解析HTML代码并记下处理的字节数。·二、以行或段的形式保存解析输出的文本。·三、统计每一行文本相应的HTML代码的字节数·四、通过计算文本相对于字节数的比率来获取文本密度·五、最后用神经网络来决定这一行是不是正文的一部分。仅仅通过判断行密度是否高于一个固定的阈值(或者就使用平均值)你就可以获得非常好的结果。但你也可以使用机器学习(这易于实现,简直不值一提)来减少这个系统出现的错误。现在让我从头开始……转换HTML为文本你需要一个文本模式浏览器的核心,它应该已经内建了读取HTML文件和显示原始文本功能。通过重用已有代码,你并不需要把很多时间花在处理无效的XML文件上。我们将使用Python来完成这个例子,它的htmllib模块可用以解析HTML文件,formatter模块可用以输出格式化的文本。嗯,实现的顶层函数如下:defextract_text(html):#Derivefromformatter.AbstractWritertostoreparagraphs.writer=LineWriter()#Defaultformattersendscommandstoourwriter.formatter=AbstractFormatter(writer)#Derivefromhtmllib.HTMLParsertotrackparsedbytes.parser=TrackingParser(writer,formatter)#GivetheparsertherawHTMLdata.parser.feed(html)parser.close()#Filtertheparagraphsstoredandoutputthem.returnwriter.output()TrackingParser覆盖了解析标签开始和结束时调用的回调函数,用以给缓冲对象传递当前解析的索引。通常你不得不这样,除非你使用不被推荐的方法——深入调用堆栈去获取执行帧。这个类看起来是这样的:classTrackingParser(htmllib.HTMLParser):"""Trytokeepaccuratepointerofparsinglocation."""def__init__(self,writer,*args):htmllib.HTMLParser.__init__(self,*args)self.writer=writer defparse_starttag(self,i):index=htmllib.HTMLParser.parse_starttag(self,i)self.writer.index=indexreturnindexdefparse_endtag(self,i):self.writer.index=ireturnhtmllib.HTMLParser.parse_endtag(self,i)LinWriter的大部分工作都通过调用formatter来完成。如果你要改进或者修改程序,大部分时候其实就是在修改它。我们将在后面讲述怎么为它加上机器学习代码。但你也可以保持它的简单实现,仍然可以得到一个好结果。具体的代码如下:classParagraph:def__init__(self):self.text=''self.bytes=0self.density=0.0classLineWriter(formatter.AbstractWriter):def__init__(self,*args):self.last_index=0self.lines=[Paragraph()]formatter.AbstractWriter.__init__(self)defsend_flowing_data(self,data):#Workoutthelengthofthistextchunk.t=len(data)#We'veparsedmoretext,soincrementindex.self.index+=t#Calculatethenumberofbytessincelasttime.b=self.index-self.last_indexself.last_index=self.index#Accumulatethisinformationincurrentline.l=self.lines[-1]l.text+=datal.bytes+=bdefsend_paragraph(self,blankline):"""Createanewparagraphifnecessary."""ifself.lines[-1].text=='':returnself.lines[-1].text+='n'*(blankline+1)self.lines[-1].bytes+=2*(blankline+1)self.lines.append(Writer.Paragraph())defsend_literal_data(self,data):self.send_flowing_data(data)defsend_line_break(self): self.send_paragraph(0)这里代码还没有做输出部分,它只是聚合数据。现在我们有一系列的文字段(用数组保存),以及它们的长度和生成它们所需要的HTML的大概字节数。现在让我们来看看统计学带来了什么。数据分析幸运的是,数据里总是存在一些模式。从下面的原始输出你可以发现有些文本需要大量的HTML来编码,特别是标题、侧边栏、页眉和页脚。虽然HTML字节数的峰值多次出现,但大部分仍然低于平均值;我们也可以看到在大部分低HTML字节数的字段中,文本输出却相当高。通过计算文本与HTML 字节数的比率(即密度)可以让我们更容易明白它们之间的关系:密度值图更加清晰地表达了正文的密度更高,这是我们的工作的事实依据。过滤文本行过滤文本行的最简单方法是通过与一个阈值(如50%或者平均值)比较密度值。下面来完成LineWriter类:defcompute_density(self):"""Calculatethedensityforeachline,andtheaverage."""total=0.0forlinself.lines:l.density=len(l.text)/float(l.bytes)total+=l.density#Storeforoptionalusebytheneuralnetwork.self.average=total/float(len(self.lines))defoutput(self):"""Returnastringwiththeuselesslinesfilteredout."""self.compute_density()output=StringIO.StringIO()forlinself.lines:#Checkdensityagainstthreshold.#Customfilterextensionsgohere.ifl.density>0.5:output.write(l.text) 监督式机器学习这是一个标识文本行是否为正文的接口界面:所谓的监督式学习就是为算法提供学习的例子。在这个案例中,我们给定一系列已经由人标识好的文档——我们知道哪一行必须输出或者过滤掉。我们用使用一个简单的神经网络作为感知器,它接受浮点输入并通过“神经元”间的加权连接过滤信息,然后输后另一个浮点数。大体来说,神经元数量和层数将影响获取最优解的能力。我们的原型将分别使用单层感知器(SLP)和多层感知器(MLP)模型。我们需要找些数据来供机器学习。之前的LineWriter.output()函数正好派上用场,它使我们能够一次处理所有文本行并作出决定哪些文本行应该输出的全局结策。从直觉和经验中我们发现下面的几条原则可用于决定如何过滤文本行:·当前行的密度·当前行的HTML字节数·当前行的输出文本长度·前一行的这三个值·后一行的这三个值我们可以利用FANN的Python接口来实现,FANN是FastArtificialNeuralNetWork库的简称。基本的学习代码如下:frompyfannimportfann,libfann#Thiscreatesanewsingle-layerperceptronwith1outputand3inputs.obj=libfann.fann_create_standard_array(2,(3,1))ann=fann.fann_class(obj)#Loadthedatawedescribedabove.patterns=fann.read_train_from_file('training.txt')ann.train_on_data(patterns,1000,1,0.0) #Thentestitwithdifferentdata.fordatin,datoutinvalidation_data:result=ann.run(datin)print'Got:',result,'Expected:',datout尝试不同的数据和不同的网络结构是比较机械的过程。不要使用太多的神经元和使用太好的文本集合来训练(过拟合),相反地应当尝试解决足够多的问题。使用不同的行数(1L-3L)和每一行不同的属性(1A-3A)得到的结果如下:有趣的是作为一个猜测的固定阈值,0.5的表现非常好(看第一列)。学习算法并不能仅仅通过比较密度来找出更佳的方案(第二列)。使用三个属性,下一个SLP比前两都好,但它引入了更多的假阴性。使用多行文本也增进了性能(第四列),最后使用更复杂的神经网络结构比所有的结果都要更好,在文本行过滤中减少了80%错误。注意:你能够调整误差计算,以给假阳性比假阴性更多的惩罚(宁缺勿滥的策略)。结论从任意HTML文件中抽取正文无需编写针对文件编写特定的抽取程序,使用统计学就能获得令人惊讶的效果,而机器学习能让它做得更好。通过调整阈值,你能够避免出现鱼目混珠的情况。它的表现相当好,因为在神经网络判断错误的地方,甚至人类也难以判定它是否为正文。现在需要思考的问题是用这些“干净”的正文内容做什么应用好呢?解析网页内容的好代码from sgmllib import SGMLParserimport urllibclass URLLister(SGMLParser):    def reset(self):        SGMLParser.reset(self)        self.urls = []    def start_a(self, attrs):        href = [v for k, v in attrs if k =='href']        if href:            self.urls.extend(href) if __name__ == '__main__':    usock = urllib.urlopen('www.xxx.com')    parser = URLLister()    parser.feed(usock.read())    usock.close()    for url in parser.urls:        print urlpython模块之HTMLParser:解析html,获取urlHTMLParser是python用来解析html的模块。它可以分析出html里面的标签、数据等等,是一种处理html的简便途径。HTMLParser采用的是一种事件驱动的模式,当HTMLParser找到一个特定的标记时,它会去调用一个用户定义的函数,以此来通知程序处理。它主要的用户回调函数的命名都是以handler_开头的,都是HTMLParser的成员函数。当我们使用时,就从HTMLParser派生出新的类,然后重新定义这几个以handler_开头的函数即可。这几个函数包括:handle_startendtag处理开始标签和结束标签handle_starttag处理开始标签,比如handle_endtag处理结束标签,比如handle_charref处理特殊字符串,就是以&#开头的,一般是内码表示的字符handle_entityref处理一些特殊字符,以&开头的,比如 handle_data处理数据,就是data中间的那些数据handle_comment处理注释handle_decl处理的东西这里我以从网页中获取到url为例,介绍一下。要想获取到url,肯定是要分析标签,然后取到它的href属性的值。下面是代码:#-*-encoding:gb2312-*-importHTMLParserclassMyParser(HTMLParser.HTMLParser):def__init__(self):HTMLParser.HTMLParser.__init__(self) defhandle_starttag(self,tag,attrs):#这里重新定义了处理开始标签的函数iftag=='a':#判断标签的属性forname,valueinattrs:ifname=='href':printvalueif__name__=='__main__':a='test链接到163'my=MyParser()#传入要分析的数据,是html的。my.feed(a)本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/zhaoweikid/archive/2007/06/13/1649997.aspx利用Python抓取和解析网页(一)对搜索引擎、文件索引、文档转换、数据检索、站点备份或迁移等应用程序来说,经常用到对网页(即HTML文件)的解析处理。事实上,通过Python语言提供的各种模块,我们无需借助Web服务器或者Web浏览器就能够解析和处理HTML文档。本文将详细介绍如何利用Python抓取和解析网页。首先,我们介绍一个可以帮助简化打开位于本地和Web上的HTML文档的Python模块,然后,我们论述如何使用Python模块来迅速解析在HTML文件中的数据,从而处理特定的内容,如链接、图像和Cookie等。最后,我们会给出一个规整HTML文件的格式标签的例子,通过这个例子您会发现使用python处理HTML文件的内容是非常简单的一件事情。  一、解析URL  通过Python所带的urlparse模块,我们能够轻松地把URL分解成元件,之后,还能将这些元件重新组装成一个URL。当我们处理HTML文档的时候,这项功能是非常方便的。  importurlparse  parsedTuple=urlparse.urlparse(  "http://www.google.com/search?   hl=en&q=urlparse&btnG=Google+Search")  unparsedURL=urlparse.urlunparse((URLscheme,  URLlocation,URLpath,'','',''))  newURL=urlparse.urljoin(unparsedURL,  "/module-urllib2/request-objects.html")  函数urlparse(urlstring[,default_scheme[,allow_fragments]])的作用是将URL分解成不同的组成部分,它从urlstring中取得URL,并返回元组(scheme,netloc,path,parameters,query,fragment)。注意,返回的这个元组非常有用,例如可以用来确定网络协议(HTTP、FTP等等)、服务器地址、文件路径,等等。  函数urlunparse(tuple)的作用是将URL的组件装配成一个URL,它接收元组(scheme,netloc,path,parameters,query,fragment)后,会重新组成一个具有正确格式的URL,以便供Python的其他HTML解析模块使用。  函数urljoin(base,url[,allow_fragments])的作用是拼接URL,它以第一个参数作为其基地址,然后与第二个参数中的相对地址相结合组成一个绝对URL地址。函数urljoin在通过为URL基地址附加新的文件名的方式来处理同一位置处的若干文件的时候格外有用。需要注意的是,如果基地址并非以字符/结尾的话,那么URL基地址最右边部分就会被这个相对路径所替换。比如,URL的基地址为Http://www.testpage.com/pub,URL的相对地址为test.html,那么两者将合并成http://www.testpage.com/test.html,而非http://www.testpage.com/pub/test.html。如果希望在该路径中保留末端目录,应确保URL基地址以字符/结尾。  下面是上面几个函数的详细一点的用法举例:importurlparse  URLscheme="http"  URLlocation="www.python.org"  URLpath="lib/module-urlparse.html"  modList=("urllib","urllib2",  "httplib","cgilib" )  #将地址解析成组件  print"用Google搜索python时地址栏中URL的解析结果"  parsedTuple=urlparse.urlparse(  "http://www.google.com/search?  hl=en&q=python&btnG=Google+Search")  printparsedTuple  #将组件反解析成URL  print"反解析python文档页面的URL"  unparsedURL=urlparse.urlunparse(  (URLscheme,URLlocation,URLpath,'','',''))  print"t"+unparsedURL  #将路径和新文件组成一个新的URL  print" 利用拼接方式添加更多python文档页面的URL"  formodinmodList:  newURL=urlparse.urljoin(unparsedURL,  "module-%s.html"%(mod))  print"t"+newURL  #通过为路径添加一个子路径来组成一个新的URL  print" 通过拼接子路径来生成Python文档页面的URL"  newURL=urlparse.urljoin(unparsedURL,  "module-urllib2/request-objects.html")  print"t"+newURL 上述代码的执行结果如下所示:  用Google搜索python时地址栏中URL的解析结果  ('http','www.google.com','/search','',  'hl=en&q=python&btnG=Google+Search','')  反解析python文档页面的URL  http://www.python.org/lib/module-urlparse.html  利用拼接方式添加更多python文档页面的URL  http://www.python.org/lib/module-urllib.html  http://www.python.org/lib/module-urllib2.html  http://www.python.org/lib/module-httplib.html  http://www.python.org/lib/module-cgilib.html  通过拼接子路径来生成Python文档页面的URL  http://www.python.org/lib/module-urllib2/request-objects.html  二、打开HTML文档  上面介绍了如何解析页面的URL,现在开始讲解如何通过URL打开一个网页。实际上,Python所带的urllib和urllib2这两个模块为我们提供了从URL打开并获取数据的功能,当然,这包括HTML文档。  importurllib  u=urllib.urlopen(webURL)  u=urllib.urlopen(localURL)  buffer=u.read()  printu.info()   print"从%s读取了%d字节数据. "%(u.geturl(),len(buffer))  若要通过urllib模块中的urlopen(url[,data])函数打开一个HTML文档,必须提供该文档的URL地址,包括文件名。函数urlopen不仅可以打开位于远程web服务器上的文件,而且可以打开一个本地文件,并返回一个类似文件的对象,我们可以通过该对象从HTML文档中读出数据。  一旦打开了HTML文档,我们就可以像使用常规文件一样使用read([nbytes])、readline()和readlines()函数来对文件进行读操作。若要读取整个HTML文档的内容的话,您可以使用read()函数,该函数将文件内容作为字符串返回。  打开一个地址之后,您可以使用geturl()函数取得被获取网页的真正的URL。这是很有用的,因为urlopen(或使用的opener对象)也许会伴随一个重定向。获取的网页URL也许和要求的网页URL不一样。  另一个常用的函数是位于从urlopen返回的类文件对象中的info()函数,这个函数可以返回URL位置有关的元数据,比如内容长度、内容类型,等等。下面通过一个较为详细的例子来对这些函数进行说明。  importurllib  webURL="http://www.python.org"  localURL="index.html"  #通过URL打开远程页面  u=urllib.urlopen(webURL)  buffer=u.read()  printu.info()  print"从%s读取了%d字节数据. "%(u.geturl(),len(buffer))  #通过URL打开本地页面  u=urllib.urlopen(localURL)  buffer= u.read()  printu.info()  print"从%s读取了%d字节数据. "%(u.geturl(),len(buffer))  上面代码的运行结果如下所示:  Date:Fri,26Jun200910:22:11GMT  Server:Apache/2.2.9(Debian)DAV/2SVN/1.5.1mod_ssl/2.2.9OpenSSL/0.9.8gmod_wsgi/2.3Python/2.5.2  Last-Modified:Thu,25Jun200909:44:54GMT  ETag:"105800d-46e7-46d29136f7180"  Accept-Ranges:bytes  Content-Length:18151  Connection:close  Content-Type:text/html  从http://www.python.org读取了18151字节数据.  Content-Type:text/html  Content-Length:865  Last-modified:Fri,26Jun200910:16:10GMT  从index.html读取了865字节数据.  三、小结  对搜索引擎、文件索引、文档转换、数据检索、站点备份或迁移等应用程序来说,经常用到对网页(即HTML文件)的解析处理。事实上,通过Python语言提供的各种模块,我们无需借助Web服务器或者Web浏览器就能够解析和处理HTML文档。本文中,我们介绍了一个可以帮助简化打开位于本地和Web上的HTML文档的Python模块。在下篇中,我们将论述如何使用Python模块来迅速解析在HTML文件中的数据,从而处理特定的内容,如链接、图像和Cookie等。 利用Python抓取和解析网页(二)对搜索引擎、文件索引、文档转换、数据检索、站点备份或迁移等应用程序来说,经常用到对网页(即HTML文件)的解析处理。事实上,通过Python语言提供的各种模块,我们无需借助Web服务器或者Web浏览器就能够解析和处理HTML文档。本文上篇中,我们介绍了一个可以帮助简化打开位于本地和Web上的HTML文档的Python模块。在本文中,我们将论述如何使用Python模块来迅速解析在HTML文件中的数据,从而处理特定的内容,如链接、图像和Cookie等。同时还会介绍如何规范HTML文件的格式标签。  一、从HTML文档中提取链接  Python语言还有一个非常有用的模块HTMLParser,该模块使我们能够根据HTML文档中的标签来简洁、高效地解析HTML文档。所以,在处理HTML文档的时候,HTMLParser是最常用的模块之一。  importHTMLParser  importurllib  classparseLinks(HTMLParser.HTMLParser):  defhandle_starttag(self,tag,attrs):  iftag=='a':  forname,valueinattrs:  ifname=='href':  printvalue  printself.get_starttag_text()  lParser=parseLinks()  lParser.feed(urllib.urlopen("http://www.python.org/index.html").read())  处理HTML文档的时候,我们常常需要从其中提取出所有的链接。使用HTMLParser模块后,这项任务将变得易如反掌。首先,我们需要定义一个新的HTMLParser类,以覆盖handle_starttag()方法,我们将使用这个方法来显示所有标签的HRef属性值。   定义好新的HTMLParser类之后,需要创建一个实例来返回HTMLParser对象。然后,就可以使用urllib.urlopen(url)打开HTML文档并读取该HTML文件的内容了。  为了解析HTML文件的内容并显示包含其中的链接,可以使用read()函数将数据传递给HTMLParser对象。HTMLParser对象的feed函数将接收数据,并通过定义的HTMLParser对象对数据进行相应的解析。需要注意,如果传给HTMLParser的feed()函数的数据不完整的话,那么不完整的标签会保存下来,并在下一次调用feed()函数时进行解析。当HTML文件很大,需要分段发送给解析器的时候,这个功能就会有用武之地了。下面是一个具体的例子  importHTMLParser  importurllib  importsys  #定义HTML解析器  classparseLinks(HTMLParser.HTMLParser):  defhandle_starttag(self,tag,attrs):  iftag=='a':  forname,valueinattrs:  ifname=='href':  printvalue  printself.get_starttag_text()  #创建HTML解析器的实例  lParser=parseLinks()  #打开HTML文件  lParser.feed(urllib.urlopen(  "http://www.python.org/index.html" ).read())  lParser.close()  上述代码的运行结果太长,在此省略,您可以自己运行代码试试。二、从HTML文档中提取图像  处理HTML文档的时候,我们常常需要从其中提取出所有的图像。使用HTMLParser模块后,这项任务将变得易如反掌。首先,我们需要定义一个新的HTMLParser类,以覆盖handle_starttag()方法,该方法的作用是查找img标签,并保存src属性值所指的文件。  importHTMLParser  importurllib  defgetImage(addr):  u=urllib.urlopen(addr)  data=u.read()  classparseImages(HTMLParser.HTMLParser):  defhandle_starttag(self,tag,attrs):  iftag=='img':  forname,valueinattrs:  ifname=='src':  getImage(urlString+"/"+value)  u=urllib.urlopen(urlString)  lParser.feed(u.read())  定义好新的HTMLParser类之后,需要创建一个实例来返回HTMLParser对象。然后,就可以使用urllib.urlopen(url)打开HTML文档并读取该HTML文件的内容了。   为了解析HTML文件的内容并显示包含其中的图像,可以使用feed(data)函数将数据发送至HTMLParser对象。HTMLParser对象的feed函数将接收数据,并通过定义的HTMLParser对象对数据进行相应的解析。下面是一个具体的示例:  importHTMLParser  importurllib  importsys  urlString="http://www.python.org"  #把图像文件保存至硬盘  defgetImage(addr):  u=urllib.urlopen(addr)  data=u.read()  splitPath=addr.split('/')  fName=splitPath.pop()  print"Saving%s"%fName  f=open(fName,'wb')  f.write(data)  f.close()  #定义HTML解析器  classparseImages(HTMLParser.HTMLParser):  defhandle_starttag(self,tag,attrs):  iftag=='img':  forname,valueinattrs:  ifname=='src' :  getImage(urlString+"/"+value)  #创建HTML解析器的实例  lParser=parseImages()  #打开HTML文件  u=urllib.urlopen(urlString)  print"OpeningURL ===================="  printu.info()  #把HTML文件传给解析器  lParser.feed(u.read())  lParser.close()  上述代码的运行结果如下所示:  OpeningURL  ====================  Date:Fri,26Jun200910:54:49GMT  Server:Apache/2.2.9(Debian)DAV/2SVN/1.5.1mod_ssl/2.2.9OpenSSL/0.9.8gmod_wsgi/2.3Python/2.5.2  Last-Modified:Thu,25Jun200909:44:54GMT  ETag:"105800d-46e7-46d29136f7180"  Accept-Ranges:bytes  Content-Length:18151  Connection:close  Content-Type:text/html  Saving python-logo.gif  Savingtrans.gif  Savingtrans.gif  Savingafnic.fr.png三、从HTML文档中提取文本  处理HTML文档的时候,我们常常需要从其中提取出所有的文本。使用HTMLParser模块后,这项任务将变得非常简单了。首先,我们需要定义一个新的HTMLParser类,以覆盖handle_data()方法,该方法是用来解析并文本数据的。  importHTMLParser  importurllib  classparseText(HTMLParser.HTMLParser):  defhandle_data(self,data):  ifdata!=' ':  urlText.append(data)  lParser=parseText()  lParser.feed(urllib.urlopen(  http://docs.python.org/lib/module-HTMLParser.html).read())  定义好新的HTMLParser类之后,需要创建一个实例来返回HTMLParser对象。然后,就可以使用urllib.urlopen(url)打开HTML文档并读取该HTML文件的内容了。  为了解析HTML文件的内容并显示包含其中的文本,我们可以使用feed(data)函数将数据传递给HTMLParser对象。HTMLParser对象的feed函数将接收数据,并通过定义的HTMLParser对象对数据进行相应的解析。要注意的是,如果传给HTMLParser的feed()函数的数据不完整的话,那么不完整的标签会保存下来,并在下一次调用feed()函数时进行解析。当HTML文件很大,需要分段发送给解析器的时候,这个功能就会有用武之地了。下面是一个具体的代码示例:   importHTMLParser  importurllib  urlText=[]  #定义HTML解析器  classparseText(HTMLParser.HTMLParser):  defhandle_data(self,data):  ifdata!=' ':  urlText.append(data)  #创建HTML解析器的实例  lParser=parseText()  #把HTML文件传给解析器  lParser.feed(urllib.urlopen(  “http://docs.python.org/lib/module-HTMLParser.html”  ).read())  lParser.close()  foriteminurlText:  printitem  上面代码的运行输出过长,在此略过四、从HTML文档中提取Cookies  很多时候,我们都需要处理Cookie,幸运的是Python语言的cookielib模块为我们提供了许多自动处理在HTML中的HTTPCookie的类。当处理要求为客户端设置Cookie的HTML文档的时候,这些类对我们非常有用。   importurllib2  importcookielib  fromurllib2importurlopen,Request  cJar=cookielib.LWPCookieJar()  opener=urllib2.build_opener(  urllib2.HTTPCookieProcessor(cJar))  urllib2.install_opener(opener)  r=Request(testURL)  h=urlopen(r)  forind,cookieinenumerate(cJar):  print"%d-%s"%(ind,cookie)  cJar.save(cookieFile)  为了从HTML文档提取cookies,首先得使用cookielib模块的LWPCookieJar()函数创建一个cookiejar的实例。LWPCookieJar()函数将返回一个对象,该对象可以从硬盘加载Cookie,同时还能向硬盘存放Cookie。  接下来,使用urllib2模块的build_opener([handler,...])函数创建一个opener对象,当HTML文件打开时该对象将处理cookies。函数build_opener可以接收零个或多个处理程序(这些程序将按照它们被指定的顺序连接在一起)作为参数并返回一个。  注意,如果想让urlopen()使用opener对象来打开HTML文件的话,可以调用install_opener(opener)函数,并将opener对象传给它。否则,请使用opener对象的open(url)函数来打开HTML文件。  一旦已经创建并安装了opener对象,就可以使用urllib2模块中的Request(url)函数来创建一个Request对象,然后就能使用urlopen(Request)函数来打开HTML文件了。   打开HTML页面后,该页面的所有Cookie将被存放到LWPCookieJar对象中,之后,您可以使用LWPCookieJar对象的save(filename)函数了。  importos  importurllib2  importcookielib  fromurllib2importurlopen,Request  cookieFile="cookies.dat"  testURL='http://maps.google.com/'  #为cookiejar创建实例  cJar=cookielib.LWPCookieJar()  #创建HTTPCookieProcessor的opener对象  opener=urllib2.build_opener(  urllib2.HTTPCookieProcessor(cJar))  #安装HTTPCookieProcessor的opener  urllib2.install_opener(opener)  #创建一个Request对象  r=Request(testURL)  #打开HTML文件  h=urlopen(r)  print"页面的头部 ======================"  printh.info()  print"页面的Cookies ======================"   forind,cookieinenumerate(cJar):  print"%d-%s"%(ind,cookie)  #保存cookies  cJar.save(cookieFile)  上述代码的运行结果如下所示:  页面的头部  ======================  Cache-Control:private  Content-Type:text/html;charset=ISO-8859-1  Set-Cookie:PREF=ID=5d9692b55f029733:NW=1:TM=1246015608:LM=1246015608:S=frfx--b3xt73TaEA;expires=Sun,26-Jun-201111:26:48GMT;path=/;domain=.google.com  Date:Fri,26Jun200911:26:48GMT  Server:mfe  Expires:Fri,26Jun200911:26:48GMT  Transfer-Encoding:chunked  Connection:close  页面的Cookies  ======================  0-五、为HTML文档中的属性值添加引号  前面我们讨论了如果根据HTML解析器中的某种处理程序来解析HTML文件,可是有时候我们却需要使用所有的处理程序来处理HTML文档。值得庆幸的是,使用HTMLParser模块解析HTML文件的所有要素并不比处理链接或者图像难多少。   importHTMLParser  importurllib  classparseAttrs(HTMLParser.HTMLParser):  defhandle_starttag(self,tag,attrs):  ...  attrParser=parseAttrs()  attrParser.init_parser()  attrParser.feed(urllib.urlopen("test2.html").read())  这里,我们将讨论如何使用HTMLParser模块来解析HTML文件,从而为“裸奔”的属性值加上引号。首先,我们要定义一个新的HTMLParser类,以覆盖下面所有的处理程序来为属性值添加引号。  handle_starttag(tag,attrs)  handle_charref(name)  handle_endtag(tag)  handle_entityref(ref)  handle_data(text)  handle_comment(text)  handle_pi(text)  handle_decl(text)  handle_startendtag(tag,attrs)  我们还需要在parser类中定义一个函数来初始化用于存储解析好的数据的变量,同时还要定义另外一个函数来返回解析好的数据。  定义好新的HTMLParser类之后,需要创建一个实例来返回HTMLParser 对象。使用我们创建的init函数初始化该解析器,这样,我们就可以使用urllib.urlopen(url)打开HTML文档并读取该HTML文件的内容了。  为了解析HTML文件的内容并给属性值添加引号,可以使用feed(data)函数将数据传递给HTMLParser对象。HTMLParser对象的feed函数将接收数据,并通过定义的HTMLParser对象对数据进行相应的解析。下面是一个具体的示例代码:  importHTMLParser  importurllib  importsys  #定义HTML解析器  classparseAttrs(HTMLParser.HTMLParser):  definit_parser(self):  self.pieces=[]  defhandle_starttag(self,tag,attrs):  fixedAttrs=""  #forname,valueinattrs:  forname,valueinattrs:  fixedAttrs+="%s="%s""%(name,value)  self.pieces.append("<%s%s>"%(tag,fixedAttrs))  defhandle_charref(self,name):  self.pieces.append("&#%s;"%(name))  defhandle_endtag(self,tag):  self.pieces.append(""%(tag))  defhandle_entityref(self,ref):  self.pieces.append("&%s"% (ref))  defhandle_data(self,text):  self.pieces.append(text)  defhandle_comment(self,text):  self.pieces.append(""%(text))  defhandle_pi(self,text):  self.pieces.append(""%(text))  defhandle_decl(self,text):  self.pieces.append(""%(text))  defparsed(self):  return"".join(self.pieces)  #创建HTML解析器的实例  attrParser=parseAttrs()  #初始化解析器数据  attrParser.init_parser()  #把HTML文件传给解析器  attrParser.feed(urllib.urlopen("test2.html").read())  #显示原来的文件内容  print"原来的文件 ========================"  printopen("test2.html").read()  #显示解析后的文件  print"解析后的文件 ========================"  printattrParser.parsed()   attrParser.close()  我们还需要建立一个测试文件,名为test2.html,该文件内容可以从上述代码的运行结果看到,具体如下所示:原来的文件========================Web页面

Web页面清单

Python网站本地页面解析后的文件========================Web页面

Web页面清单

Python网站本地页面  六、小结对搜索引擎、文件索引、文档转换、数据检索、站点备份或迁移等应用程序来说,经常用到对网页(即HTML文件)的解析处理。事实上,通过Python语言提供的各种模块,我们无需借助Web服务器或者Web浏览器就能够解析和处理HTML文档。本文将详细介绍了如何使用Python模块来迅速解析在HTML 文件中的数据,从而处理特定的内容,如链接、图像和Cookie等。同时,我们还给出了一个规范HTML文件的格式标签的例子,希望本文对您会有所帮助。Python读取网页并保存代码如下:importsysimporturllib2importosprint("Parametercount:",len(sys.argv))iflen(sys.argv)<3:   print("Parameterrequired:")   print("SavingHttpPageTool.exe[WebPageAddress][savingPath]")   exit(0)name=sys.argv[2]ifos.path.exists(name):   print("removefile:"+name)   os.remove(name)print("getpage:"+sys.argv[1])req=urllib2.Request(sys.argv[1])res=urllib2.urlopen(req)##headers=str(res.info())##print(headers)html=res.read()print("writefile:"+name)writeFile=file(name,'w')writeFile.write(html)writeFile.close()print("finished")python正则小试读取网页内容2个月前坛子里有道友问的shell问题,当时用python草草写下一个简单的脚本,今天无意中翻出贴出来已做备用#!/usr/bin/envpython #-*-coding:UTF-8-*-#Author:wanghaoyu-wanghaoyu1625@gmail.com#QQ:42030925#Lastmodified:2010-04-1914:04#Filename:web.py#Description:importos,urllib,urllib2importre,sysurl="http://jt.sz.bendibao.com/bus/linesearch.aspx?line=615&x=0&y=0"page=urllib.urlopen(url).read()pat=re.compile(r'
(.*?)',flags=20)cont=pat.search(page).group(1)cont=re.sub(r'<(.*?)>','',cont)printcont输出结果是:            运营时间:5:50-21:20            票价:上车2元,全程7元            往程:七十二区总站-金威啤酒厂-新福市场-宝城批发市场-宝安海关大厦-宝安党校-新安影剧院-恒丰商场-沁园公园-教育培训中心-恒丰中心-宝安税务局-宝安海雅百货-冠利达大厦-建安新村-北方公司-西乡路口-臣田-固戍-劲力集团-三围路口-中华商贸城- 鹤洲路口-钟屋-翠湖花园-机场路口-下十围-白石厦-福永工业区-凤凰工业区- 福永汽车站凤凰分站-上南油站-沙井电子城-上寮市场-上南酒店-上寮市场-沙井天虹商场-万丰派出所-万丰工业区-马鞍山市场-茭塘工业区-大王山-三洋马达厂-沙一村-海欣花园-安托山科技园-海上田园风光-国富康总站            返程:国富康总站-海上田园风光-安托山科技园-海欣花园-沙一村-三洋马达厂-大王山-茭塘工业区-马鞍山市场-万丰工业区- 万丰派出所-沙井天虹商场-上寮市场-沙井电子城-上南油站-福永汽车站凤凰分站-凤凰工业区-福永工业区-白石厦-下十围-机场路口-翠湖花园-钟屋-鹤洲路口-中华商贸城-三围路口-劲力集团-固戍-臣田-西乡路口-北方公司-建安新村-冠利达大厦-宝安海雅百货-宝安税务局-恒丰中心-教育培训中心-沁园公园-恒丰商场-新安影剧院-宝安党校-宝安海关大厦-宝城批发市场-新福市场-金威啤酒厂-七十二区总站抓取網頁的最佳語言:Python最初最早我用C/C++語言慢慢寫抓網頁的用它來抓網頁真的是程式,一開始甚至打算自己寫抓取網頁的函式庫,想說當做練習,可是HTTP協定雖然不難,可是煩,要處理的細節太多了,後來受不了,轉而使用現成的Library:cUrl,但是C/C++語言開發這類東西的效率實在太慢了,我的程式不停的修改、不停的修改,光是編譯的時間就吃掉了不知道多少,字串的處理C/C++沒有內建正規表示法或一些好用的字串函數之類的,處理起來也礙手礙腳,當時,我想將我寫好的函數庫寫成能讓Lua呼叫的形式,或著甚是C/C++來呼叫Lua,因為C/C++有很多細節要處理,Memoryleak有的沒有的雜事,我想要的只是專注在寫抓取網頁的程式,因此用Lua包裝似乎是不錯的選擇,但是開發時間太久了,事情一直沒有變好直到 我下了一個結論,C/C++不適合寫抓取網頁的程式,我開始思考我需要什麼,我想我既然要包裝成其它語言將細節藏起來,為何不直接使用script語言?我最早一直擔心的是效率的問題,但是到後來想想反正真正沒效率的部份包給C/C++去做事實上沒有太大的差別,而且又有動態語言的彈性、除錯上的方便等等好處,何樂不為?於是我開始尋找一款合適的語言Perl如何?很早以前我有用Perl寫過一些CGI程式、留言版、網站管理系統、文章管理系統等等,有人說Perl是只能寫一次的語言,它有很多很簡短的符號所構成的表示法,可讀性不是很好,模組化設計也沒有非常好的支援,OO也是一樣,新版的Perl遲遲沒有推出,似乎已經有點變成遺產的感覺,或許是上面的理由還是偏見,總而言之我不喜歡PerlPHP?做為一個以網頁為主要用途的語言,拿來當做其它用途總有種不太合適的感覺,從它的語法來看,很明顯是參考C語言、Perl等等而來的,但是卻沒有加以改進,我個人認為它可能沒有預料到PHP居然會紅成這樣,變成網頁程式設計的主流語言,後來有很多缺點就變得顯而易見,不夠嚴僅的語法、不夠好的模組化設計、不良的OO支援、容易寫出安全性有問題的程式等等,命名空間也是它一大缺點之一,光是看到一大堆前綴字開頭的函數就有種倒胃口的感覺,有人說PHPistheBASICofthe21stcentury在這個影片裡,總合種種理由,做為抓取網頁的用途,PHP出局LuaLua做為輕量級的語言相當的優秀,可是你不會想用Lua來寫大型的程式,我也不會想這麼做,它語言的設計都是以速度為優先考量,寫起來並不怎麼順手的感覺,再加上目前的資源不多,可能很多東西都得自行包裝,這樣就和我原先想做的事是一樣的,因此不考慮LuaJavaJava是和網路一起成長的程式語言,做為抓取網頁的用途,它絕對有能力勝任,但是…,我嫌它太囉唆了,還有太癡肥,當一款語言太囉唆和太癡肥往往會令人討厭,歐!想到Java我就想起eclipse在我那台只有256 扣掉分給顯示記憶體的筆電上執行的情況,讓我想把電腦砸掉,不好意思,我不喜歡Java在前面的影片裡的老兄一樣也有提到,有興趣可以看看JavaistheCOBOLofthe21stcenturyPython最後,我在PTT的程式設計討論版上描述了我的需求,有人推文說Python,我抓了抓頭髮,Python?WTF?這是什麼?我從來沒有聽過這款語言,於是上網找了一下資料,和問了一些問題,發現這款語言正是我想要的,它很容易被擴充,因此效能不足可以用C/C++補強,你想得到的函式庫幾乎都已經有人寫好了,光從下載網頁這件工作來看,它的標準函式庫已經有了這樣的功能,你覺得不夠好還有其它很多的選擇,開箱即用的哲學,讓安裝函式庫非常簡單,不像C/C++的編譯惡夢讓你抓光頭髮,而它最優秀的地方之一就是它的可讀性,寫起來相當順手、優雅,讀起來也一樣順眼,重要的是很有趣,那麼開發大型的程式呢?script語言常見的問題就是對於開發大型程式來說很不適合,但是Python卻不是如此,良好的OO、模組化等等它都有良好的支援,再加上Google也是Python的愛用者,YouTube也是用Python開發的,有了這些大咖背書,證明這款語言的確是相當優秀,在決定使用Python之後我就立刻訂購了一本LearningPython,開始學習Python愛上PythonPython並沒有讓我失望,能用Python寫的東西都不太想用C/C++去寫,開發效率非常高、寫起來很順手、豐富的資源,讓我覺得這真的是優秀的語言,它的確很適合拿來抓取網頁,不過抓取網頁還有更多東西要考慮Twisted用Python抓取網頁的HTML只是小菜一盤,用Python標準函數庫就辦得到,但不是那麼好用,最後我發現了Twisted,就改用Twisted來抓網頁,它有優秀的非同步事件驅動的架構,常見的協定都已經有實做,包括HTTP、SMTP等等,用它來抓網頁真的是再容易不過了getPage("http://www.google.com").addCallback(printPage)是的,一行就可以抓網頁,夠簡單吧,而且你想要傳POST或GET等參數,或是修改HTTP的header都沒有問題BeautifulSoup 抓網頁事實上不是什麼難事,解析HTML要來得更麻煩,最初使用Python的標準函式庫內建的HTMLParser來解析網頁,但是功能太陽春,加上最頭痛的問題是,大部份的網頁都沒有完全尊照標準來寫,各種莫明奇妙的錯誤令人想要找出那個寫網頁的人痛打他一頓,為了解決容錯的問題,一開始我使用BeautifulSoup來抓取網頁,它是以容錯著名的HTMLParser,但是,它的效率很差,又或著說,找到目標HTML標籤的方式很沒效率,一般都用find等方式來找到所要的標籤soup.find('div',dict(id='content'))它真的很沒效率,當你抓取大一點的網頁時,多塞幾個一起抓和解析,你就會看見你的CPU使用率永遠是滿的狀態,原本我預計抓網頁的瓶頸都會落在網路IO上面,但是用它來抓取網頁卻超出我預料,沒想到它會這麼吃重,於是沒辦法,我開始尋找更好的選擇lxml我找到一個Blog的文章:PythonHTMLParserPerformance,介紹了Python各種Parser的效能,效能最亮眼的,就是lxml,我最初擔心的是找到資料標籤會不會很困難,但是我發現它支援xpath,就試著改寫原本BeautifulSoup用find等等函數寫的尋找標籤程式,發現xpath遠比那種方式來得好用太多了,而且效率好太多了,BeautifulSoup的find極度的沒有效率,大部份的CPU時間都耗在一堆find函數走訪HTML樹上,而xpath篩選標籤的方式來得有效率多了,以下舉幾個我實際用在抓取網頁的案子中的例子defgetNextPageLink(self,tree):"""Getnextpagelink @paramtree:treetogetlink@return:Returnurlofnextpage,ifthereisnonextpage,returnNone"""paging=tree.xpath("//span[@class='paging']")ifpaging:links=paging[0].xpath("./a[(text(),'%s')]"%self.localText['next'])iflinks:returnstr(links[0].get('href'))returnNone listPrice=tree.xpath("//*[@class='priceBlockLabel']/following-sibling::*")iflistPrice:detail['listPrice']=self.stripMoney(listPrice[0].text)原本使用BeautifulSoup在尋找標籤遇到麻煩的走訪羅輯上的問題還得寫程式解決,xpath本身就有豐富的語法可以提供各種篩選的條件,羅輯從程式碼被移到了xpath語法上,有了這樣的語法,尋找目標標籤輕鬆了許多,而且效率也很好,從此我就和BeautifulSoup說再見,改用lxml來找標籤配合FireFox的工具如果有一些工具可以幫助寫解析網頁的程式該有多好,這也是我希望能有的,使用了xpath之後,我找到了FireFox的插件,XPathchecker等xpath的工具,可以先用它來確定抓到的元素是正確的,然後FireBug在檢視網頁結構上也有很大的幫助FireFox插件XPathchecker畫面 使用FireBug檢視網頁元素結論就目前一路走過來的經驗來看,抓取網頁Python的確是最佳的選擇,不過我們到目前為止我們都只討論到工具,事實上還有設計上的問題要解決,留在下一次寫Python读取网页并保存(转)http://houzhengqing.blog.163.com/blog/static/22754987200982813739833/代码如下:importsysimporturllib2importosprint("Parametercount:",len(sys.argv))iflen(sys.argv)<3:   print("Parameterrequired:")   print("SavingHttpPageTool.exe[WebPageAddress][savingPath]")   exit(0)name=sys.argv[2]ifos.path.exists(name):   print("removefile:"+name)   os.remove(name)print("getpage:"+sys.argv[1])req=urllib2.Request(sys.argv[1])res=urllib2.urlopen(req)##headers=str(res.info())##print(headers)html=res.read()print("writefile:"+name)writeFile=file(name,'w')writeFile.write(html)writeFile.close()print("finished") 用Python读取网页最近信号处理与机器翻译课要交作业,其中一项是网页采集器,又称spider。爬虫从一个或若干初始网页的URL开始,获得初始网页上的URL,在抓取网页的过程中,不断从当前页面上抽取新的URL放入队列,直到满足系统的一定停止条件。Python很适合这类与网络有关的工作。下了个Phthon2.5,居然自带PythonManuals,连借书都免了。只看Manuals大概就明白了。因为有好多功能健全的lib,用Python抓取网页是如此简单:  importurllib                  urlItem=urllib.urlopen("http://www.baidu.com")   htmSource=urlItem.read()   urlItem.close()显示网页的内容:  printhtmSource显示的是html文件内容。我在VC里用这个来实现的:CInternetSessionsession,这是MFC封装的CInternetSessionsession;//建立一个Internet会话CInternetFile*file=NULL;CStringm_buffer;try{file=(CInternetFile*)session.OpenURL(url);}catch(CInternetException*pEx){file=NULL;pEx->Delete();}if(file){CStringline;for(inti=0;file->ReadString(line);i++){m_buffer+=line+"r ";}file->Close();deletefile;}python访问网页(摘自刘鑫的博客)简单的抓取网页:import urllib.request  url="http://google.cn/"  response=urllib.request.urlopen(url)  #返回文件对象page=response.read()   有个办法直接将URL保存为本地文件:import urllib.request  url="http://www.xxxx.com/1.jpg"urllib.request.urlretrieve(url,r"d:temp1.jpg")  网页抓取实际上分为2步:第一步是发出请求,第二步接收服务器返回的数据,在Python中也是这么做的.POST方式:01.importurllib.parse  02.importurllib.request  03. 04.url="http://liuxin-blog.appspot.com/messageboard/add" 05. 06.values={"content":"命令行发出网页请求测试"}  07.data=urllib.parse.urlencode(values) 08.09.#创建请求对象  10.req=urllib.request.Request(url,data) 11.#获得服务器返回的数据  12.response=urllib.request.urlopen(req) 13.#处理数据  14.page=response.read() GET方式:01.importurllib.parse  02.importurllib.request  03. 04.url="http://www.google.cn/webhp" 05. 06.values={"rls":"ig"}  07.data=urllib.parse.urlencode(values)  08. 09.theurl=url+"?"+data 10.#创建请求对象  11.req=urllib.request.Request(theurl) 12.#获得服务器返回的数据  13.response=urllib.request.urlopen(req) 14.#处理数据  15.page=response.read()  有2个常用的方法,geturl(),info()geturl()的设置是为了辨别是否有服务器端的网址重定向,而info()则包含了一系列的信息。中文问题的处理,会用到encode()编码dencode()解码:[python]用urllib2设置代理访问网页#!/usr/bin/envpythonimport urllib2#changefollowingsbeforeuseuser='foo'passwd='bar'proxyserver='1.2.3.4:5'url  ='http://www.google.com/'defproxy1():   #work   proxy='http://%s:%s@%s'%(user,passwd,proxyserver)   opener=urllib2.build_opener(urllib2.ProxyHandler({'http':proxy}))   urllib2.install_opener(opener)   sContent=urllib2.urlopen(url)   printsContent.read()defproxy2():   #workforsomeone,butnotforme   passmgr=urllib2.HTTPPasswordMgrWithDefaultRealm()   passmgr.add_password('realm',proxyserver,user,passwd)   authinfo=urllib2.ProxyBasicAuthHandler(passmgr)   proxy='http://%s'%proxyserver   opener=urllib2.build_opener(urllib2.ProxyHandler({'http':proxy}),authinfo)   urllib2.install_opener(opener)   sContent=urllib2.urlopen(url)   printsContent.read()defproxy3():   #workforsomeone,butnotforme   authinfo=urllib2.HTTPBasicAuthHandler()   authinfo.add_password('realm',proxyserver,user,passwd)      proxy='http://%s'%proxyserver   opener=urllib2.build_opener(urllib2.ProxyHandler({'http':proxy}),authinfo)   urllib2.install_opener(opener)      sContent=urllib2.urlopen(url)   printsContent.read() 在linux系统中,如果urllib2设置的代理不好用可以试试环境变量: exporthttp_proxy='protocol://user:passwd@proxyserver:port'exporthttps_proxy='protocol://user:passwd@proxyserver:port' 比如通过代理上传appengine文件,其SDK中的rpc不提供代理设置,就可以用这招。python访问网页带cookie问题我现在要用python访问一个网站的网页,取得一些信息但是网站要求先登录,然后才能继续访问,登录过程就是写了个cookie请问下python访问网页怎么保持住cookie呢?我用的是python3.1,只有urllib和http两个库了网上找了一些代码,都是python2.x版本的哪位好心的兄弟写几句python3.1的代码,感激不尽在httpheader中加入Cookie即可,参考下列代码:Pythoncodeheaders=[("Cookie",cookiestr)]request=urllib2.Request(self.url)opener=urllib2.build_opener()opener.addheaders=headersstream=opener.open(request)html=stream.read()---------------------这个简单Pythoncode #coding:UTF-8importurllib2,httplib,urllib,sys,cookielibif__name__=="__main__":cj=cookielib.CookieJar()body=(('staffNo','mop用户名'),('password','mop密码'))opener=urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))opener.addheaders=[('User-agent','Mozilla/4.0(compatible;MSIE6.0;WindowsNT5.1)')]urllib2.install_opener(opener)req=urllib2.Request(url,urllib.urlencode(body))u=urllib2.urlopen(req)#printu.read().decode('utf-8').encode('gbk')url='http://app.mop.com/tycoon/'u=urllib2.urlopen(url)u=urllib2.urlopen('http://app.mop.com/tycoon/myEmpire.do');printu.read().decode('utf-8').encode('gbk')编写Python程序访问需要cookie的网页importurllib2,cookielib,urllib,httplib,recookie=cookielib.CookieJar()opener=urllib2.build_opener(urllib2.HTTPCookieProcessor(cookie))urllib2.install_opener(opener)str= "email=******&password=****&origURL=%2FSysHome.do&submit=%E7%99%BB%E5%BD%95"rexp=re.compile(r'<')frquene=[]login=urllib2.urlopen("http://www.xiaonei.com/Login.do",str)res=login.read()#printrescond=Truei=0whilecond:    cond=False    frlist_url="http://xiaonei.com/myfriendlist.do?curpage=%d&univ="%(i,)    print"!!",frlist_url    i=i+1    frlist=urllib2.urlopen(frlist_url)    res=frlist.read()    print"!!",res    lines=res.split(" ")    forlineinlines:        a=rexp.search(line)        ifa:            cond=True            frquene.append(a.groups()[0])            forfrinfrquene:    printfr用Python写点东西,模拟post访问网页#加个这个东东看看能不能好 importurllibimporthttp.clientheaders={'Accept-Language':'zh-cn','Accept-Charset':'gb18030,utf-8','Accept-Encoding':'gzip,deflate,bzip2,sdch','User-Agent':'Mozilla/5.0(Windows;U;WindowsNT5.1)','Connection':'Keep-Alive'}params={'querytype':'1','offset':'0','select':'北京'}#所需要的参数conn=http.client.HTTPConnection('www.shpost.com.cn')conn.request('post','/customer/customer_chaxunjieguo.php',params,headers)res=conn.getresponse()data=res.read()file('d:\a.html','wb').write(data)报错:File"D:/MyDocuments/妗岄潰/url_o.py",line10,inFile"D:ProgramFilesPythonlibhttpclient.py",line862,inrequest   self._send_request(method,url,body,headers)File"D:ProgramFilesPythonlibhttpclient.py",line908,in_send_request   self.send(body)File"D:ProgramFilesPythonlibhttpclient.py",line689,insend   self.sock.sendall(str)TypeError:sendall()argument1mustbebytesorbuffer,notdict更新:今天过来写了点新东东,看到这,也更新下吧,前段时候就解决了,因为我用的是Python3.0,urllib进行了大量的修改以及增强,在3.0的Python中没有urllib2这个库了,能用的都增强到urllib中了,现在的写法很简单了:importurllib.parseimporturllib.requesturl="http://www.shpost.com.cn/customer/customer_chaxunjieguo.php"values={"querytype":1,"offset":0}data=urllib.parse.urlencode(values)+"&select="+urllib.parse.quote("北京".encode('gb2312'))#创建请求对象 req=urllib.request.Request(url,data,{'User-Agent':'Mozilla/5.0(Windows;U;WindowsNT5.1;zh-CN;)',"Accept-Language":"zh-cn,zh","Accept-Charset":"gb2312,utf-8"})#获得服务器返回的数据response=urllib.request.urlopen(req)#处理数据page=response.read()open('d:\a.html','wb').write(page)就这些,呵呵,简单很多了,代码少了不少,想想当初没有解决这问题的原因,应该是资料少的问题。使用python访问网站---urllib,Tkinter>>>importurllib>>>url='http://www.baidu.com/'>>>page=urllib.urlopen(url)                    #打开网站,一般需要等待一段时间。时间长短依赖于网站内容>>>data=page.read()>>>printdata百度一下,你就知道...例子:#!/usr/bin/envpython#coding=utf-8#file:httpurl.py#importTkinterimporturllibclassWindow:   def__init__(self,root):       self.root=root       self.entryUrl=Tkinter.Entry(root)       self.entryUrl.place(x=5,y=15)       self.get=Tkinter.Button(root,                                 text='下载页面',                                 command=self.Get)       self.get.place(x=120,y=15)       self.edit=Tkinter.Text(root)       self.edit.place(y=50)   defGet(self):       url=self.entryUrl.get()       page=urllib.urlopen(url)       data= page.read()       self.edit.insert(Tkinter.END,data)       page.close()root=Tkinter.Tk()window=Window(root)root.minsize(600,480)root.mainloop()自编例子:#-*_coding:utf-8-*-#file:AutoCaphttpuurl.py#importsysimportosimporturllibimporttimeErrLimt=1000defWebAnalysis(WebPage=""):   passdefGenerateName():   currenttime=time.time()   TimeString=time.ctime(currenttime)   TimeString=TimeString.replace("","")   TimeString=TimeString.replace(":","_")#   printTimeString   FileName=TimeString+'.htm'   returnFileNamedeflistDirectory(directory):   "getlistoffileinfoobjectsforfilesofparticularextensions"#   ParaTableList={}            #Saveallparametertable{'ParaTableName:':0}#   FileList=[]                 #SaveOpenFilename   print"Pleaseinputthefirsthttplink!"   print"Formatas:'http://www.hao123.com/'"   WXDownLoadLink=raw_input()           #Recordthelinknamewaitingforparase.   print"Pleaseinputthesecondhttplink!"   print"Format as:'http://www.hao123.com/'"   THDownLoadLink=raw_input()           #Recordthelinknamewaitingforparase.   data=""   ErrorCnt=0   whileTrue:       try:           page=urllib.urlopen(WXDownLoadLink)           data=page.read()       except:           print("WebLinkOpen/ReadErroroccuredat%s"%time.ctime(time.time()))           ErrorCnt+=1           ifErrorCnt>=ErrLimt:               print("ErrorCnt=%sexceedlimt%s"%(ErrorCnt,ErrLimt))               break           time.sleep(10)           continue       FileName=GenerateName()       FileName='WX'+FileName       printFileName       FileName=os.path.join(directory,FileName)       try:           file=open(FileName,'wb')           file.write(data)           file.close()           page.close()       except:           print("FileOpen/writeErroroccuredat%s"%time.ctime(time.time()))           pass       WebAnalysis(data)       data=""       try:           page=urllib.urlopen(THDownLoadLink)           data=page.read()       except:           print("WebLinkOpen/ReadErroroccuredat%s"%time.ctime(time.time()))           ErrorCnt+=1           ifErrorCnt>=ErrLimt:               print("ErrorCnt=%sexceedlimt%s"%(ErrorCnt, ErrLimt))               break           time.sleep(10)           continue       FileName=GenerateName()       FileName='KO'+FileName       printFileName       FileName=os.path.join(directory,FileName)       try:           file=open(FileName,'wb')           file.write(data)           file.close()           page.close()       except:           print("FileOpen/writeErroroccuredat%s"%time.ctime(time.time()))           pass       WebAnalysis(data)       data=""#       break       time.sleep(60*60)            #GetWebfileeveryonehour.   return0if__name__=="__main__":   result=0print"PleaseinputtheDirectoryoftheLog!"   print"WindlowsFormatas:'E:DeskTopADGLogsTextCrockett'"   print"LinuxFormatas:'/home/merlin/DlWeb'"   Filedir=raw_input()   result=listDirectory(Filedir)   ifresult:       print"Thereissomethingerroroccured!"python抓网页的编码问题小弟刚接触python,抓第一个网页就过不去编码这个坎`请高手赐教,代码如下:#coding=gb2312importurllib2fromBeautifulSoupimportBeautifulSoupoutfile=open("lsxk.txt","w")foriinrange(1,2):#第一页url="http://bbs.scu.edu.cn/wForum/disparticle.php? boardName=SCUExpress&ID=1735295349&pos=-1&page=%d"%idoc=urllib2.urlopen(url).read()soup=BeautifulSoup(doc,fromEncoding="gb2312")print>>outfile,doc#输出到文本outfile.close()抓到txt中的内容是中文,但使用beautifulSoup后就乱码了`BS的文档说使用soup=BeautifulSoup(doc,fromEncoding="gb2312"),还是不能正确编码.print出来报错是gb2312和utf-8不能编码网页中的某些字符.单独使用编码也不能解决:importcodecsprintopen("lsxk.txt").read().decode("utf-8")可能说的不是很清楚`以上是我遇到的问题们,还请高手帮帮忙,不甚感谢!最佳答案BeautifulSoup版本有问题,使用3.03就可以了importurllib2fromBeautifulSoupimportBeautifulSoupf=urllib.urlopen('http://www.baidu.com')html=f.read()f.close()soup=BeautifulSoup()soup.feed(html)printsoupPython抓取网页图片相关代码编写方法利用Python编程语言进行网页内容的抓取是一个比较常用的编程技术。那么,今天我们将会为大家详细介绍一下有关Python抓取网页图片的操作方法,以方便大家在实际应用中获得一些帮助。Python抓取网页图片代码示例:1.ImgDownloader 2.import win32com.client,time,win32inet,win32file,os 3.class ImgDownloader:  1.def __init__(self,url,dir): 2.self.__dir=dir 3.self.__ie=win32com.client.Dispatch('InternetExplorer.Application') 4.self.__ie.Navigate(url) 5.self.__wait__() 6.def __wait__(self): 7.while self.__ie.Busy: 8.time.sleep(0.1) 9.def start(self): 10.self.__wait__() 11.imgs=self.__ie.Document.getElementsByTagName('img') 12.for i in range(imgs.length): 13.try: 14.cachInfo=win32inet.GetUrlCacheEntryInfo(imgs[i].src) 15.if cachInfo: 16.path=cachInfo['LocalFileName'] 17.pathpathinfo=path.split('\') 18.pathinfo.reverse() 19.filename=('[%d]' % i) + pathinfo[0] 20.win32file.CopyFile(path,os.path.join(self.__dir,filename),True) 21.except: 22.pass 23.def close(self): 24.self.__ie.Quit() 25.if __name__=='__main__': 26.d=ImgDownloader('http://image.baidu.com/i?ct=201326592&cl=2&lm=-1&tn=baiduimage&pv=&word=boy&z=0','c:\temp\') 27.d.start() 28.d.close() 原理:在Python使用com接口运行IE浏览器,然后打开网页,获取网页所有图片的URL,最后利用win32api函数GetUrlCacheEntryInfo找出图片相应的本地缓存文件,复制到指定目录。以上就是我们为大家介绍的Python抓取网页图片的应用方式。BeautifulSoupPython抓网页小例子收藏viewplaincopytoclipboardprint?01.#-*-coding:utf-8-*-02.importurllib203.fromBeautifulSoupimportBeautifulSoup,Tag04.importre05.page= urllib2.urlopen("http://bj.ganji.com/piao/zz_%E5%8C%97%E4%BA%AC-%E5%8D%97%E6%98%8C/20100210/")06.soup=BeautifulSoup(page)07.#ss=soup.findAll('a',href=re.compile(r"^/piao/100."))08.ss=soup.findAll(attrs={"class":"list_piao"})09.fp=open("c:\Python25\web.html","w")10.doc='''''<htmlxmlns="http://www.w3.org/1999/xhtml">11.<head>12.<metahttp-equiv="Content-Type"content="text/html;charset=utf-8"/>13.<title>keyunqtickets14.15.16.17..list_piaodt{float:left;width:40%;line-height:24px;font-size:14px;text-indent:5px;padding:5px0;}20.21.'''22.fp.write('%s '%doc)23.foriinss:24.i.dt['class']='list_piao_time'25.tmp=i.a['href']26.i.a['href']='http://bj.ganji.com'+tmp27.phonepage=urllib2.urlopen(i.a['href'])28.phonesoup=BeautifulSoup(phonepage)29.phone=phonesoup.findAll(attrs={"class":"phoneNum"})30.tmp=phone[0].img['src']31.phone[0].img['src']='http://bj.ganji.com'+tmp32.tag1=Tag(soup,"dd")33.tag1['class']='list_piao_mj'34.i.insert(8,tag1)35.text=str(phone[0].img)36.tag1.insert(1,text)37.printi38.#i.dd.insert(0,str(phone[0].img))39.fp.write('%s '%i)40.doc='''''41.'''42.fp.write('%s '%doc) 43.fp.close()#-*-coding:utf-8-*-importurllib2fromBeautifulSoupimportBeautifulSoup,Tagimportrepage=urllib2.urlopen("http://bj.ganji.com/piao/zz_%E5%8C%97%E4%BA%AC-%E5%8D%97%E6%98%8C/20100210/")soup=BeautifulSoup(page)#ss=soup.findAll('a',href=re.compile(r"^/piao/100."))ss=soup.findAll(attrs={"class":"list_piao"})fp=open("c:\Python25\web.html","w")doc='''keyunqtickets.list_piaodt{float:left;width:40%;line-height:24px;font-size:14px;text-indent:5px;padding:5px0;}'''fp.write('%s '%doc)foriinss:i.dt['class']='list_piao_time'tmp=i.a['href']i.a['href']='http://bj.ganji.com'+tmpphonepage=urllib2.urlopen(i.a['href'])phonesoup=BeautifulSoup(phonepage)phone=phonesoup.findAll(attrs={"class":"phoneNum"})tmp=phone[0].img['src']phone[0].img['src']='http://bj.ganji.com'+tmptag1=Tag(soup,"dd")tag1['class']='list_piao_mj'i.insert(8,tag1)text=str(phone[0].img)tag1.insert(1,text) printi#i.dd.insert(0,str(phone[0].img))fp.write('%s '%i)doc=''''''fp.write('%s '%doc)fp.close()BeautifulSoup是用Python写的一个HTML/XML的解析器,它可以很好的处理不规范标记并生成剖析树(parsetree)。它提供简单又常用的导航(navigating),搜索以及修改剖析树的操作。它可以大大节省你的编程时间。BeautifulSoup中文文档地址本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/keyunq/archive/2010/02/02/5282174.aspxPython抓网页内容用Python语言写搜索引擎蜘蛛的脚本非常简单、轻松。给大家分享两种抓网页内容的方法一、用urllib2/sgmllib包,将目标网页的所有URL列出。importurllib2fromsgmllibimportSGMLParserclassURLLister(SGMLParser):  defreset(self):                   SGMLParser.reset(self)    self.urls=[]  defstart_a(self,attrs):              href=[vfork,vinattrsifk=='href']    ifhref:      self.urls.extend(href)f=urllib2.urlopen("http://www.donews.com/")iff.code==200:  parser=URLLister()  parser.feed(f.read())  f.close()  forurlinparser.urls:printurl二、用python调用IE抓取目标网页(Requirewin32com,pythoncom)的所有图像的url和大小importwin32com.client, pythoncomimporttimeie=win32com.client.DispatchEx('InternetExplorer.Application.1')ie.Visible=1ie.Navigate("http://news.sina.com.cn")whileie.Busy:  time.sleep(0.05)doc=ie.Documentforiindoc.images:  printi.src,i.width,i.height这种方法可以利用IE本身的Javascript.DHTML的支持,来做自动提交Form,和处理Javascript。有关样例可以参考http://win32com.dePython爬虫1)Python版简单网络爬虫URLLister类,负责从HTML文本中根据标签提取URL,但也会提取一些垃圾URL,有待改进fromsgmllibimportSGMLParserclassURLLister(SGMLParser):defreset(self):SGMLParser.reset(self)self.urls=[]defstart_a(self,attrs):href=[vfork,vinattrsifk=='href']ifhref: self.urls.extend(href)getURL(url)用来将HTML中的url放入urls列表中importurllib,urllisterdefgetURL(url):try:usock=urllib.urlopen(url)except:print'geturlexcepton'return[]parser=urllister.URLLister()parser.feed(usock.read())usock.close()parser.close()urls=parser.urlsreturnurlsspider(startURL,depth)递归调用getURL(url),startURL为起始URL,depth为递归次数,及遍历的深度defspider(startURL,depth):i=0globalnum#num为全局变量,用来记录打印的url的数目ifdepth<=i:return0else:urls=getURL(startURL)iflen(urls)>0:forurlinurls:printurl,numnum=num+1spider(url,depth-1)else:return0return1调用spidernum=0spider("http://www.xjtu.edu.cn/",2)运行结果: 得到962个url,不过其中有一些不符合URL格式的“假货”,比如“nav.php?type=2944”“http://gs.xjtu.edu.cn/zhaos/upload/files/462498fcd3d35.doc285”等而且每次到.doc这里都会很费时间,可见这个“假货”处理速度很慢。用正则表达式可以判断URL的合法性,待续……(2)小小的爬虫程序Python有一个urllib的库,可以很方便的从给定的url抓取网页,以下这段程序实现了抓取一个url并存到指定文件的功能:  爬虫工作的基本原理就是,给定一个初始的url,下载这个url的网页,然后找出网页上所有满足下载要求的链接,然后把这些链接对应的url下载下来,然后再找下载下来的这些网页的url,我们可以用广度优先搜索实现这个算法,不过,首先得有一个函数找出网页上所有的满足要求的url,下面这个例子用正则表达式找出url.  最后就是广度优先搜索了,这个实现起来也很简单:  作者用上面的算法,感觉速度还行,1小时可以抓10000多网页,可以满足小型系统的要求。(3)小爬虫1.0----Spider.py--------#!/usr/local/bin/pythonfrommySpiderimport*defmain():mySpider=miniHTMLParser()Site=mySpider.site_find()forsinSite: mySpider.search_keyword=str(s.contents[27].contents[0]).strip()domain=str(s.contents[1].contents[0]).strip()root_url=str(s.contents[3].contents[0]).strip()variable_url=str(s.contents[5].contents[0]).strip()image_save_location=str(s.contents[7].contents[0]).strip()image_name_len=s.contents[9].contents[0]image_name_len=int(image_name_len.strip())html_file=str(s.contents[11].contents[0]).strip()xml_file=str(s.contents[25].contents[0]).strip()description_index=str(s.contents[13].contents[0]).strip()description_keyword=str(s.contents[15].contents[0]).strip()name_index=str(s.contents[17].contents[0]).strip()name_keyword=str(s.contents[19].contents[0]).strip()image_index=str(s.contents[21].contents[0]).strip()image_keyword=str(s.contents[23].contents[0]).strip()link=root_url+variable_urlxmlist=[]#whilelink!='':whilelink!=root_url:print" Checkinglink",domain+linkraw_html=mySpider.gethtmlfile(domain,link)mySpider.raw_html=raw_htmlmySpider.encode='utf-8'cleaned_html=mySpider.html_feed()#GetContentclean_theater_name=mySpider.clean_html(name_index,name_keyword)clean_theater_description=mySpider.clean_html(description_index,description_keyword)#SaveImagetry:image_html_source=mySpider.soup_find_from_source(image_index,image_keyword)image_url=mySpider.soup_find_img_src(domain,image_html_source)image_name=link[image_name_len:].replace('=','0')image_name=image_name.replace('/','')image_local=image_save_location+domain+image_url[-4:]mySpider.save_image(image_name,domain,image_url)except:image_url='None'image_local='None' xmlist.append(('theater',[('name',clean_theater_name),('description',clean_theater_description),('image_remote',image_url),('image_local',image_local)]))mySpider.save_html(html_file,cleaned_html)mySpider.feed(cleaned_html)next_link=mySpider.get_next_link()ifnext_link[0:1]!='/':next_link=root_url+next_linklink=next_linkmySpider.close()print" done "xml_input=('Spider',[('Content',xmlist)])mySpider.save_xml(xml_file,xml_input)if__name__=="__main__":main()---mySpider.py----#!/usr/local/bin/pythonimporthttplibimportsysimportrefrompyfoimportpyfoimporturllib2fromBeautifulSoupimportBeautifulSoup,SoupStrainer,BeautifulStoneSoupfromHTMLParserimportHTMLParserclassminiHTMLParser(HTMLParser):viewedQueue=[]instQueue=[]search_keyword=''encode='utf-8'raw_html=''config='config.xml'defget_next_link(self):ifself.instQueue==[]: return''else:returnself.instQueue.pop(0)defgethtmlfile(self,site,page):try:httpconn=httplib.HTTPConnection(site)httpconn.request("GET",page)resp=httpconn.getresponse()resppage=resp.read()except:resppage=""returnresppagedefhandle_starttag(self,tag,attrs):iftag=='a':newstr=str(attrs[0][1])ifre.search('http',newstr)==None:ifre.search('mailto',newstr)==None:ifre.search(self.search_keyword,newstr)!=None:if(newstrinself.viewedQueue)==False:print"adding",newstrself.instQueue.append(newstr)self.viewedQueue.append(newstr)else:print"ignoring",newstrelse:print"ignoring",newstrelse:print"ignoring",newstrdefclean_html(self,index,keyword):soup=self.get_soup()html_source=str(soup.findAll(attrs={index:re.compile(keyword+"$")}))clean_html_source=re.sub('<(?!(?:as|/a|!))[^>]*>','',html_source)clean_html_source=clean_html_source.replace(' ','')clean_html_source=clean_html_source.replace('[','')clean_html_source=clean_html_source.replace(']','')clean_html_source=clean_html_source.strip()returnclean_html_sourcedefclean_description_list(self,index,keyword): clean_description_list=[]clean_html_source=self.clean_html(index,keyword)t=clean_html_source.split(':')forgint:g=g.strip()s=g.split('')fortagins:iftag!='':tag=tag.strip()tag=tag[0:10]iftag!='www.example1.com.cn/movie/ theater.aspimage/-2CrawlingPage/piao.htmlbgcolor#2B2B2Bbgcolor#4B4B4Bwidth169CrawingContent/piao.xmltheater.aspwww.example.com/theater/intro/BeiJing/CHANGHONG/image/-5CrawlingPage/mvgod.htmlclassmainclassnamezistylefloat:right;margin:4pxCrawingContent/mvgod.xml/theater/intro/BeiJing/(4)用python编写网络爬虫 刚刚开了一个《计算机网络》的课,觉得很有用。正好师兄让我练习编写一个能下载网站网页的程序,正好能用上课上的知识了。为了想作一个效率不差的,而下载网页的性能瓶颈是在网络上,所有决定用Python编写代码。刚学python没几天,学习一种语言的最好方法就是写code.下面的是我用的多线程实现的网络爬虫,并用py2exe生成了一个exe,自身觉得py2exe不太好,又不会更好的,只能......这是我这些天的成果。希望有人能提出好的建议,先谢谢了!一共两个文件,一个是toolbox_insight.py,是一个工具文件另一个是test.py,是一个用到toolbox_insight.py中工具的测试文件#FileName:toolbox_insight.pyfromsgmllibimportSGMLParserimportthreadingimporttimeimporturllib2importStringIOimportgzipimportstringimportos#rewriteSGMLParserforstart_aclassBasegeturls(SGMLParser):#这个Basegeturls类作用是分析下载的网页,把网页中的所有链接放在self.url中。defreset(self):self.url=[]SGMLParser.reset(self)defstart_a(self,attrs):href=[vfork,vinattrsifk=='href']ifhref:self.url.extend(href)#forquicklyfindingclassNewlist(list):#这个类其实是一个添加了find方法的LIST。当num变量在LIST中,返回True,当不在LIST中,返回False并把num按二分法插入LIST中deffind(self,num):l=len(self)first=0end=l-1mid=0ifl==0:self.insert(0,num)returnFalsewhilefirstself[mid]:first=mid+1elifnumnum:self.insert(first,num)returnFalseelifself[first]end:self.insert(first,num)returnFalseelse:returnTrue#下面的reptile顾名思义是一个爬虫classreptile(threading.Thread):#Name:是爬虫是名字,queue是任务队列,所有的爬虫共用同一个任务队列#从中取出一个任务项进行运行,每个任务项是一个要下载网页的URL#result:也是一个队列,将下载的网页中包含的URL放入该队列中#inittime:在本程序中没有用,只是一个为了以后扩展用的#downloadway:是下载的网页存放的路径#configfile:是配置文件,存放网页的URL和下载下后的路径#maxnum:每个爬虫有个最大下载量,当下载了这么多网页后,爬虫deaddef__init__(self,Name,queue,result,Flcok,inittime=0.00001,downloadway='D:\bbs\',configfile='D:\bbs\conf.txt',maxnum=10000):threading.Thread.__init__(self,name=Name)self.queue=queueself.result=resultself.Flcok=Flcokself.inittime=inittimeself.mainway=downloadwayself.configfile=configfileself.num=0#已下载的网页个数self.maxnum=maxnumos.makedirs(downloadway+self.getName())#系统调用:在存放网页的文件夹中创建一个以该爬虫name为名字的文件夹self.way=downloadway+self.getName()+'\'defrun(self):opener=urllib2.build_opener()#创建一个开启器whileTrue:url=self.queue.get()#从队列中取一个URLifurl==None: #当取得一个None后表示爬虫结束工作,用于外部方便控制爬虫的生命期breakparser=Basegeturls()#创建一个网页分析器request=urllib2.Request(url)#网页请求request.add_header('Accept-encoding','gzip')#下载的方式是gzip压缩后的网页,gzip是大多数服务器支持的一种格式try:#这样可以减轻网络压力page=opener.open(request)#发送请求报文ifpage.code==200:#当请求成功predata=page.read()#下载gzip格式的网页pdata=StringIO.StringIO(predata)#下面6行是实现解压缩gzipper=gzip.GzipFile(fileobj=pdata)try:data=gzipper.read()except(IOError):print'unusedgzip'data=predata#当有的服务器不支持gzip格式,那么下载的就是网页本身try:parser.feed(data)#分析网页except:print'Iamhere'#有的网页分析不了,如整个网页就是一个图片foriteminparser.url:self.result.put(item)#分析后的URL放入队列中way=self.way+str(self.num)+'.html'#下面的是网页的保存,不多说了self.num+=1file=open(way,'w')file.write(data)file.close()self.Flcok.acquire()confile=open(self.configfile,'a')confile.write(way+''+url+' ')confile.close()self.Flcok.release()page.close()ifself.num>=self.maxnum:#达到最大量后退出breakexcept:print'enderror'#和爬虫一样是个线程类,作用是将爬虫中的result中存入的URL加以处理。只要同一个服务器的网页classproinsight(threading.Thread):def__init__(self,queue,list,homepage,inqueue):threading.Thread.__init__(self) self.queue=queue#和爬虫中的result队列是同一个self.list=list#是上面Newlist的对象self.homepage=homepage#主页self.inqueue=inqueue#处理完后的URL的去处defrun(self):length=len(self.homepage)whileTrue:item=self.queue.get()ifitem==None:breakifitem[0:4]=='r ':item=item[4:]ifitem[-1]=='/':item=item[:-1]iflen(item)>=len('http://')anditem[0:7]=='http://':iflen(item)>=lengthanditem[0:length]==self.homepage:ifself.list.find(item)==False:self.inqueue.put(item)elifitem[0:5]=='/java'oritem[0:4]=='java':passelse:ifitem[0]!='/':item='/'+itemitem=self.homepage+itemifself.list.find(item)==False:self.inqueue.put(item)下面的是一个主函数过程我下载的网站是http://bbs.hit.edu.cn开始网页是http://bbs.hit.edu.cn/mainpage.php#FileName:testfromtoolbox_insightimport*fromQueueimportQueueimportthreadingimportsysnum=int(raw_input('Enterthenumberofthread:'))pnum=int(raw_input('Enterthenumberofdownloadpages:'))mainpage=str(raw_input('Themainpage:'))startpage=str(raw_input('Startpage:'))queue=Queue()key=Queue()inqueue=Queue()list=Newlist()thlist=[]Flock=threading.RLock() foriinrange(num):th=reptile('th'+str(i),queue,key,Flock)thlist.append(th)pro=proinsight(key,list,mainpage,inqueue)pro.start()foriinthlist:i.start()queue.put(startpage)foriinrange(pnum):queue.put(inqueue.get())foriinrange(num):queue.put(None)个人觉得用wxpython来实现用户界面和用数据库知识查找URL是更好的扩展方向用python编写分布式爬虫1、网络连接需要持续连接(persistentconnection),DNS解析的瓶颈(先查本地DNS缓存)实现方法:基于pythonhttplib(对http1.1完成对持续连接的支持(python的httplib完全支持http1.1),如果不是http1.1那么可以使用urlopen对其进行一次连接)并对其socket对象进行控制,关键是加入对读取DNS本地缓存(在我的机制下这个根本就不是主要问题可以暂时忽略),以及有settimeout(Igloo)(搞定,就用setdefaulttimeout())的支持(或者利用自己的DNS服务器,进行优化处理),以及对sock对象的settimeout进行设置,防止长时间的等待一个有可能连接不上的web服务器.(要测试一下连接模块和DNS解析模块在访问不存在url在默认情况下的时间消耗)对站点的ip解析出来后就直接用ip进行连接而避免了重复调用DNS解析.例子:socket.gethostbyname("www.163.com")网络连接下载模块非常重要,需要精心反复测试,因为有可能碰到一些不规范的web服务器,如果没有加以考虑会使整个线程崩溃。2、多线程:机器任务的分配及站点任务的分配。实现方法:(在某台机器上实现,在对本机内存cpu的消耗情况判断后对机器任务进行分配;在对和站点的连接情况进行判断后对站点任务进行分配)机器任务的分配:对于机器负担的情况调整在一个机器开的线程的个数。(在关闭线程时注意要先让线程完成当前运行任务)站点任务的分配:就是某个机器对一个站点开的线程的个数的分配。(同样是要注意关闭线程时先让其完成当前任务) 3、对web文件树遍历过程更好的控制,对web文件树在广度优先遍历时层次的判断。(整个网络是一个图,而某个站点的模型更接近于一棵树)实现方法:在每个地址进入队列时加一个层次号,那么要遍历第n层的话那么遍历到第一个n+1就停止读取。4、利用robotparser解析robots.txt5、单个机器spider的作用:a)同2多线程3文件树的遍历b)将获取的外部url发回中央控制器,并从中央控制器取回新的外部url。6、中央控制器的作用:a)观察各机器的状态包括:cpu、内存、线程、站点、网络流量b)观察对外整体网络流量和连接状况,可以根据网络状况来调节timeout。c)接受各个机器发送过来的外部url并对每个url的重复数字计数。然后分配到各个机器。(分配时要用爬行策略控制器对外部url进行排序来分配,Igloo利用PageRank,我们可以使用最简单的重复越多重要系数就越高来进行排序)d)分布式URL分配算法:Igloo1.2的二级哈希映射算法(集中式分配算法那个中央控制器容易成为系统瓶颈)复习哈希算法,还有就是对url是否访问过的判断(Igloo使用的是URLTrie滞后合并策略)。可以使用BerkeleyDB作为URLTrie的替代品。两种实现方式的比较:i.现在的想法:(面向站点,信息颗粒大)外部链接只是保存主机名比如:www.163.com,站内访问用解析好的ip地址维持连接,用相对链接来得到各个页面,这样就要维护一个外部链接列表,几个站点的链接列表。优点:节省内存,对某个站点的信息获取全面,对站点的出现频率统计,排序,重要站点先取。缺点:对链接的获取的全面性得不到保证,而且不能获取更多的重要页面,每个站点的重要页面也不会很多。ii.老方案:(面向页面,信息颗粒小)所有连接一视同仁。缺点:浪费资源,对单一站点的获取不一定全面。优点:可以得到全面的链接图,可以使用PageRank对列表进行排序,页面更重要就在最前面。7、解析html(超级链接的提取)搞定(用python的sgmllib)缺点:速度太慢(可能会造成瓶颈,要好好包装好,以后有机会换掉它)5多线程实例viewplaincopytoclipboardprint? #-*-coding:utf-8-*-importurllib,httplibimportthreadimporttimefromQueueimportQueue,Empty,FullHEADERS={"Content-type":"application/x-www-form-urlencoded",'Accept-Language':'zh-cn','User-Agent':'Mozilla/4.0(compatible;MSIE6.0;WindowsNT5.0)',"Accept":"text/plain"}UNEXPECTED_ERROR=-1POST='POST'GET='GET'defbase_log(msg):printmsgdefbase_fail_op(task,status,log):log('failop.task=%s,status=%d'%(str(task),status))defget_remote_data(tasks,results,fail_op=base_fail_op,log=base_log):whileTrue:task=tasks.get()try:tid=task['id']hpt=task['conn_args']#hpt<=host:port,timeoutexceptKeyError,e:log(str(e))continuelog('thread_%sdoingtask%d'%(thread.get_ident(),tid))#log('hpt='+str(hpt))conn=httplib.HTTPConnection(**hpt)try:params=task['params']exceptKeyError,e:params={}params=urllib.urlencode(params)#log('params='+params)try:method=task['method']exceptKeyError:method='GET'#log('method='+method)try:url=task['url'] exceptKeyError:url='/'#log('url='+url)headers=HEADERStry:tmp=task['headers']exceptKeyError,e:tmp={}headers.update(tmp)#log('headers='+str(headers))headers['Content-Length']=len(params)try:ifmethod==POST:conn.request(method,url,params,headers)else:conn.request(method,url+params)response=conn.getresponse()exceptException,e:log('requestfailed.method=%s,url=%s,params=%sheaders=%s'%(method,url,params,headers))log(str(e))fail_op(task,UNEXPECTED_ERROR,log)continueifresponse.status!=httplib.OK:fail_op(task,response.status,log)continuedata=response.read()results.put((tid,data),True)classHttpPool(object):def__init__(self,threads_count,fail_op,log):self._tasks=Queue()self._results=Queue()foriinxrange(threads_count):thread.start_new_thread(get_remote_data,(self._tasks,self._results,fail_op,log))defadd_task(self,tid,host,url,params,headers={},method='GET',timeout=None): task={'id':tid,'conn_args':{'host':host}iftimeoutisNoneelse{'host':host,'timeout':timeout},'headers':headers,'url':url,'params':params,'method':method,}try:self._tasks.put_nowait(task)exceptFull:returnFalsereturnTruedefget_results(self):results=[]whileTrue:try:res=self._results.get_nowait()exceptEmpty:breakresults.append(res)returnresultsdeftest_google(task_count,threads_count):hp=HttpPool(threads_count,base_fail_op,base_log)foriinxrange(task_count):ifhp.add_task(i,'www.google.cn','/search?',{'q':'lai'},#method='POST'):print'addtasksuccessed.'whileTrue:results=hp.get_results()ifnotresults:time.sleep(1.0*random.random())foriinresults:printi[0],len(i[1])#printunicode(i[1],'gb18030') if__name__=='__main__':importsys,randomtask_count,threads_count=int(sys.argv[1]),int(sys.argv[2])test_google(task_count,threads_count)本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/b2b160/archive/2009/02/19/3906174.aspxPython如何使用urllib2获取网络资源·urllib2是Python的一个获取URLs(UniformResourceLocators)的组件。他以urlopen函数的形式提供了一个非常简单的接口,这是具有利用不同协议获取URLs的能力,他同样提供了一个比较复杂的接口来处理一般情况,例如:基础验证,cookies,代理和其他。它们通过handlers和openers的对象提供。urllib2支持获取不同格式的URLs(在URL的":"前定义的字串,例如:"ftp"是"ftp:python.ort/"的前缀),它们利用它们相关网络协议(例如FTP,HTTP)进行获取。这篇教程关注最广泛的应用--HTTP。对于简单的应用,urlopen是非常容易使用的。但当你在打开HTTP的URLs时遇到错误或异常,你将需要一些超文本传输协议(HTTP)的理解。最权威的HTTP文档当然是RFC2616(http://rfc.net/rfc2616.html)。这是一个技术文档,所以并不易于阅读。这篇HOWTO教程的目的是展现如何使用urllib2,并提供足够的HTTP细节来帮助你理解。他并不是urllib2的文档说明,而是起一个辅助作用。获取URLs最简单的使用urllib2将如下所示Pythoncodeimporturllib2response=urllib2.urlopen(http://python.org/)html=response.read()urllib2的很多应用就是那么简单(记住,除了"http:",URL同样可以使用"ftp:","file:"等等来替代)。但这篇文章是教授HTTP的更复杂的应用。HTTP是基于请求和应答机制的--客户端提出请求,服务端提供应答。urllib2用一个Request对象来映射你提出的HTTP请求,在它最简单的使用形式中你将用你要请求的地址创建一个Request对象,通过调用urlopen并传入Request 对象,将返回一个相关请求response对象,这个应答对象如同一个文件对象,所以你可以在Response中调用.read()。Pythoncodeimporturllib2req=urllib2.Request(http://www.voidspace.org.uk)response=urllib2.urlopen(req)the_page=response.read()记得urllib2使用相同的接口处理所有的URL头。例如你可以像下面那样创建一个ftp请求。Pythoncodereq=urllib2.Request(ftp://example.com/)在HTTP请求时,允许你做额外的两件事。首先是你能够发送data表单数据,其次你能够传送额外的关于数据或发送本身的信息("metadata")到服务器,此数据作为HTTP的"headers"来发送。接下来让我们看看这些如何发送的吧。Data数据有时候你希望发送一些数据到URL(通常URL与CGI[通用网关接口]脚本,或其他WEB应用程序挂接)。在HTTP中,这个经常使用熟知的POST请求发送。这个通常在你提交一个HTML表单时由你的浏览器来做。并不是所有的POSTs都来源于表单,你能够使用POST提交任意的数据到你自己的程序。一般的HTML表单,data需要编码成标准形式。然后做为data参数传到Request对象。编码工作使用urllib的函数而非urllib2。Pythoncodeimporturllibimporturllib2url=http://www.someserver.com/cgi-bin/register.cgi values={name:MichaelFoord,location:Northampton,language:Python}data=urllib.urlencode(values)req=urllib2.Request(url,data)response=urllib2.urlopen(req)the_page=response.read()记住有时需要别的编码(例如从HTML上传文件--看http://www.w3.org/TR/REC-html40/interact/forms.html#h-17.13HTMLSpecification,FormSubmission的详细说明)。如ugoni没有传送data参数,urllib2使用GET方式的请求。GET和POST请求的不同之处是POST请求通常有"副作用",它们会由于某种途径改变系统状态(例如提交成堆垃圾到你的门口)。尽管HTTP标准说的很清楚POSTs通常会产生副作用,GET请求不会产生副作用,但没有什么可以阻止GET请求产生副作用,同样POST请求也可能不产生副作用。Data同样可以通过在Get请求的URL本身上面编码来传送。可看如下例子Pythoncode>>>importurllib2>>>importurllib>>>data={}>>>data[name]=SomebodyHere>>>data[location]=Northampton>>>data[language]=Python>>>url_values=urllib.urlencode(data)>>>printurl_values name=Somebody+Here&language=Python&location=Northampton>>>url=http://www.example.com/example.cgi>>>full_url=url+?+url_values>>>data=urllib2.open(full_url)Headers我们将在这里讨论特定的HTTP头,来说明怎样添加headers到你的HTTP请求。有一些站点不喜欢被程序(非人为访问)访问,或者发送不同版本的内容到不同的浏览器。默认的urllib2把自己作为“Python-urllib/x.y”(x和y是Python主版本和次版本号,例如Python-urllib/2.5),这个身份可能会让站点迷惑,或者干脆不工作。浏览器确认自己身份是通过User-Agent头,当你创建了一个请求对象,你可以给他一个包含头数据的字典。下面的例子发送跟上面一样的内容,但把自身模拟成InternetExplorer。Pythoncodeimporturllibimporturllib2url=http://www.someserver.com/cgi-bin/register.cgiuser_agent=Mozilla/4.0(compatible;MSIE5.5;WindowsNT)values={name:MichaelFoord,location:Northampton,language:Python}headers={User-Agent:user_agent}data=urllib.urlencode(values)req=urllib2.Request(url,data,headers) response=urllib2.urlopen(req)the_page=response.read()response应答对象同样有两个很有用的方法。看下面的节infoandgeturl,我们将看到当发生错误时会发生什么。HandleExceptions处理异常当urlopen不能够处理一个response时,产生urlError(不过通常的PythonAPIs异常如ValueError,TypeError等也会同时产生)。HTTPError是urlError的子类,通常在特定HTTPURLs中产生。URLError通常,URLError在没有网络连接(没有路由到特定服务器),或者服务器不存在的情况下产生。这种情况下,异常同样会带有"reason"属性,它是一个tuple,包含了一个错误号和一个错误信息。例如Pythoncode>>>req=urllib2.Request(http://www.pretend_server.org)>>>try:urllib2.urlopen(req)>>>exceptURLError,e:>>>printe.reason>>>(4,getaddrinfofailed)HTTPError服务器上每一个HTTP应答对象response包含一个数字"状态码"。有时状态码指出服务器无法完成请求。默认的处理器会为你处理一部分这种应答(例如:假如response是一个"重定向",需要客户端从别的地址获取文档,urllib2将为你处理)。其他不能处理的,urlopen会产生一个HTTPError。典型的错误包含"404"(页面无法找到),"403"(请求禁止),和"401"(带验证请求)。请看RFC2616第十节有所有的HTTP错误码HTTPError实例产生后会有一个整型code属性,是服务器发送的相关错误号。ErrorCodes错误码因为默认的处理器处理了重定向(300以外号码),并且100-299范围的号码指示成功,所以你只能看到400-599的错误号码。 BaseHTTPServer.BaseHTTPRequestHandler.response是一个很有用的应答号码字典,显示了RFC2616使用的所有的应答号。这里为了方便重新展示该字典。(译者略)当一个错误号产生后,服务器返回一个HTTP错误号,和一个错误页面。你可以使用HTTPError实例作为页面返回的应答对象response。这表示和错误属性一样,它同样包含了read,geturl,和info方法。Pythoncode>>>req=urllib2.Request(http://www.python.org/fish.html)>>>try:>>>urllib2.urlopen(req)>>>exceptURLError,e:>>>printe.code>>>printe.read()>>>404Error404:FileNotFound......etc...WrappingitUp包装所以如果你想为HTTPError或URLError做准备,将有两个基本的办法。我则比较喜欢第二种。第一个:Pythoncodefromurllib2importRequest,urlopen,URLError,HTTPErrorreq=Request(someurl)try:response=urlopen(req) exceptHTTPError,e:printTheservercouldntfulfilltherequest.printErrorcode:,e.codeexceptURLError,e:printWefailedtoreachaserver.printReason:,e.reasonelse:#everythingisfine注意:exceptHTTPError必须在第一个,否则exceptURLError将同样接受到HTTPError。第二个:Pythoncodefromurllib2importRequest,urlopen,URLErrorreq=Request(someurl)try:response=urlopen(req)exceptURLError,e:ifhasattr(e,reason):printWefailedtoreachaserver.printReason:,e.reasonelifhasattr(e,code):printTheservercouldntfulfilltherequest.printErrorcode:,e.codeelse: #everythingisfineinfoandgeturlurlopen返回的应答对象response(或者HTTPError实例)有两个很有用的方法info()和geturl()geturl--这个返回获取的真实的URL,这个很有用,因为urlopen(或者opener对象使用的)或许会有重定向。获取的URL或许跟请求URL不同。info--这个返回对象的字典对象,该字典描述了获取的页面情况。通常是服务器发送的特定头headers。目前是httplib.HTTPMessage实例。经典的headers包含"Content-length","Content-type",和其他。查看QuickReferencetoHTTPHeaders(http://www.cs.tut.fi/~jkorpela/http.html)获取有用的HTTP头列表,以及它们的解释意义。Openers和Handlers当你获取一个URL你使用一个opener(一个urllib2.OpenerDirector的实例,urllib2.OpenerDirector可能名字可能有点让人混淆。)正常情况下,我们使用默认opener--通过urlopen,但你能够创建个性的openers,Openers使用处理器handlers,所有的“繁重”工作由handlers处理。每个handlers知道如何通过特定协议打开URLs,或者如何处理URL打开时的各个方面,例如HTTP重定向或者HTTPcookies。如果你希望用特定处理器获取URLs你会想创建一个openers,例如获取一个能处理cookie的opener,或者获取一个不重定向的opener。要创建一个opener,实例化一个OpenerDirector,然后调用不断调用.add_handler(some_handler_instance).同样,可以使用build_opener,这是一个更加方便的函数,用来创建opener对象,他只需要一次函数调用。build_opener默认添加几个处理器,但提供快捷的方法来添加或更新默认处理器。其他的处理器handlers你或许会希望处理代理,验证,和其他常用但有点特殊的情况。install_opener用来创建(全局)默认opener。这个表示调用urlopen将使用你安装的opener。Opener对象有一个open方法,该方法可以像urlopen函数那样直接用来获取urls:通常不必调用install_opener,除了为了方便。#include #include#include/*newforv7*/#include/*newforv7*/////这个函数是为了符合CURLOPT_WRITEFUNCTION而构造的//完成数据保存功能size_tmy_write_func(void*ptr,size_tsize,size_tnmemb,FILE*stream){returnfwrite(ptr,size,nmemb,stream);}//这个函数是为了符合CURLOPT_READFUNCTION而构造的//数据上传时使用size_tmy_read_func(void*ptr,size_tsize,size_tnmemb,FILE*stream){returnfread(ptr,size,nmemb,stream);}//这个函数是为了符合CURLOPT_PROGRESSFUNCTION而构造的//显示文件传输进度,t代表文件大小,d代表传输已经完成部分intmy_progress_func(FILE*out,doublet,/*dltotal*/ doubled,/*dlnow*/doubleultotal,doubleulnow){fprintf(out,"%d/%d(%d%%) ",(int)d,(int)t,(int)((d*100.0)/t));return0;}void*my_thread(void*ptr){CURL*curl;CURLcoderes;FILE*outfile;char*url=ptr;curl=curl_easy_init();if(curl){outfile=fopen("baidu.html","w");curl_easy_setopt(curl,CURLOPT_URL,url); curl_easy_setopt(curl,CURLOPT_WRITEDATA,outfile);curl_easy_setopt(curl,CURLOPT_WRITEFUNCTION,my_write_func);curl_easy_setopt(curl,CURLOPT_READFUNCTION,my_read_func);curl_easy_setopt(curl,CURLOPT_NOPROGRESS,0L);curl_easy_setopt(curl,CURLOPT_PROGRESSFUNCTION,my_progress_func);curl_easy_setopt(curl,CURLOPT_PROGRESSDATA,stdout);res=curl_easy_perform(curl);fclose(outfile);/*alwayscleanup*/curl_easy_cleanup(curl);}returnNULL;}intmain(intargc,char**argv){my_thread("www.baidu.com");return0;}

当前文档最多预览五页,下载文档查看全文

此文档下载收益归作者所有

当前文档最多预览五页,下载文档查看全文
温馨提示:
1. 部分包含数学公式或PPT动画的文件,查看预览时可能会显示错乱或异常,文件下载后无此问题,请放心下载。
2. 本文档由用户上传,版权归属用户,天天文库负责整理代发布。如果您对本文档版权有争议请及时联系客服。
3. 下载前请仔细阅读文档内容,确认文档内容符合您的需求后进行下载,若出现内容与标题不符可向本站投诉处理。
4. 下载文档时可能由于网络波动等原因无法下载或下载错误,付费完成后未能成功下载的用户请联系客服处理。
最近更新
更多
大家都在看
近期热门
相关标签
关闭