python抓取页面

f453 贡献于2015-10-25

作者 levin  创建于2010-11-17 06:53:00   修改者levin  修改于2010-11-17 07:55:00字数92725

文档摘要:python中如何提取网页正文。用python 下载网页内容还是很不错的,之前是使用urllib模块实验的,但听说有pycurl这个模块,而且比urllib好。
关键词:

python 中如何提取网页正文啊 谢谢 import urllib.request   url="http://google.cn/"   response=urllib.request.urlopen(url)   page=response.read()   python提取网页中的文本 1. import os,sys,datetime    2. import httplib,urllib, re    3. from sgmllib import SGMLParser    4.    5. import types    6.    7. class Html2txt(SGMLParser):    8.     def reset(self):    9.         self.text = ''   10.         self.inbody = True   11.          SGMLParser.reset(self)    12.     def handle_data(self,text):    13.         if self.inbody:    14.             self.text += text    15.    16.     def start_head(self,text):    17.         self.inbody = False   18.     def end_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.     print parser.text.strip()   python 下载网页 import httplib   conn=httplib.HTTPConnection("www.baidu.com") conn.request("GET","/index.html") r1=conn.getresponse() print r1.status,r1.reason data=r1.read() print data conn.close 用python下载网页,超级简单! from urllib import urlopen webdata = urlopen("").read() print webdata 深入python里面有 python 下载网页内容,用python的pycurl模块实现 1. 用python 下载网页内容还是很不错的,之前是使用urllib模块实验的,但听说有pycurl这个模块,而且比urllib好,所以尝试下,废话不说,以下是代码 2. 3. 4. #!/usr/bin/env python 5. # -*- coding: utf-8 -*- 6. import StringIO 7. import pycurl 8. def writefile(fstr,xfilename):   f=open(xfilename,'w')   f.write(fstr)   f.close 9. 1. html = StringIO.StringIO() 2. c = pycurl.Curl() 3. myurl='http://www.ppgchenshan.com' 4.   5. c.setopt(pycurl.URL, myurl) 6.   7. #写的回调 8. c.setopt(pycurl.WRITEFUNCTION, html.write) 9.   10. c.setopt(pycurl.FOLLOWLOCATION, 1) 11.   12. #最大重定向次数,可以预防重定向陷阱 13. c.setopt(pycurl.MAXREDIRS, 5) 14.   15. #连接超时设置 16. c.setopt(pycurl.CONNECTTIMEOUT, 60) 17. c.setopt(pycurl.TIMEOUT, 300) 18.   19. #模拟浏览器 20. c.setopt(pycurl.USERAGENT, "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)") 21.   22.   23.   24. #访问,阻塞到访问结束 25. c.perform() 26.   27. #打印出 200(HTTP状态码,可以不需要) 28. print c.getinfo(pycurl.HTTP_CODE) 29.   30. #输出网页的内容 31. print html.getvalue() 32. #保存成down.txt文件 33. writefile(html.getvalue(),"down.txt") python的pycurl模块的安装可以到http://pycurl.sourceforge.net/download/这里去找. 不同系统使用不同版本,自己看看 总结下,Python 下载网页的几种方法 1 fd = urllib2.urlopen(url_link) data = fd.read() 这是最简洁的一种,当然也是Get的方法 2 通过GET的方法 def GetHtmlSource(url): try: htmSource = '' req = urllib2.Request(url) fd = urllib2.urlopen(req,"") while 1: data = fd.read(1024) if not len(data): break htmSource += data fd.close() del fd del req htmSource = htmSource.decode('cp936') htmSource = formatStr(htmSource) return htmSource except socket.error, err: str_err = "%s" % err return "" 3 通过GET的方法 def GetHtmlSource_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() except Exception(), err: trackback.print_exec() conn.close() return htmSource 通过POST的方法 def GetHtmlSource_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() if not f: raise socket.error, "timed out" htmSource = f.read() f.close() conn.close() return htmSource except Exception(), err: trackback.print_exec() conn.close() return htmSource 本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/sding/archive/2010/04/29/5538065.aspx Django+python+BeautifulSoup组合的垂直搜索爬虫 使用python+BeautifulSoup完成爬虫抓取特定数据的工作,并使用Django搭建一个管理平台,用来协调抓取工作。 因为自己很喜欢Django admin后台,所以这次用这个后台对抓取到的链接进行管理,使我的爬虫可以应对各种后期的需求。比如分时段抓取,定期的对已经抓取的地址重新抓取。数据库是用python自带的sqlite3,所以很方便。 这几天正好在做一个电影推荐系统,需要些电影数据。本文的例子是对豆瓣电影抓取特定的数据。 第一步:建立Django模型 模仿nutch的爬虫思路,这里简化了。每次抓取任务开始先从数据库里找到未保存的(is_save = False)的链接,放到抓取链表里。你也可以根据自己的需求去过滤链接。 python代码: view plaincopy to clipboardprint? 01.class Crawl_URL(models.Model): 02. url = models.URLField('抓取地址',max_length=100, unique=True) 03. weight = models.SmallIntegerField('抓取深度',default = 0)#抓取深度起始1 04. is_save = models.BooleanField('是否已保存',default= False)# 05. date = models.DateTimeField('保存时间',auto_now_add=True,blank=True,null=True) 06. def __unicode__(self): 07. return self.url class Crawl_URL(models.Model): url = models.URLField('抓取地址',max_length=100, unique=True) weight = models.SmallIntegerField('抓取深度',default = 0)#抓取深度起始1 is_save = models.BooleanField('是否已保存',default= False)# date = models.DateTimeField('保存时间',auto_now_add=True,blank=True,null=True) def __unicode__(self): return self.url 然后生成相应的表。 还需要一个admin管理后台 view plaincopy to clipboardprint? 01.class Crawl_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) class Crawl_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-8 import urllib2 from BeautifulSoup import * from urlparse import urljoin from pysqlite2 import dbapi2 as sqlite from movie.models import * from django.contrib.auth.models import User from time import sleep image_path = 'C:/Users/soul/djcodetest/picture/' user = User.objects.get(id=1) def crawl(depth=10): for i in range(1,depth): print '开始抓取 for %d....'%i pages = Crawl_URL.objects.filter(is_save=False) newurls={} for crawl_page in pages: page = crawl_page.url try: c=urllib2.urlopen(page) except: continue try: #解析元数据和url soup=BeautifulSoup(c.read()) #解析电影页面 if re.search(r'^http://movie.douban.com/subject/(\d+)/$',page): read_html(soup) #解析出有效的链接,放入newurls links=soup('a') for link in links: if 'href' in dict(link.attrs): url=urljoin(page,link['href']) if url.find("'")!=-1: continue if len(url) > 60: continue url=url.split('#')[0] # removie location portion if re.search(r'^http://movie.douban.com', url): newurls[url]= crawl_page.weight + 1 #连接有效。存入字典中 try: print 'add url :' except: pass except Exception.args: try: print "Could not parse : %s" % args except: pass #newurls存入数据库 is_save=False weight=i crawl_page.is_save = True crawl_page.save() #休眠2.5秒 sleep(2.5) save_url(newurls) #保存url,放到数据库里 def save_url(newurls): for (url,weight) in newurls.items(): url = Crawl_URL(url=url,weight=weight) try: url.save() except: try: print 'url重复:' except: pass return True 第三步,用BeautifulSoup解析页面 抽取出电影标题,图片,剧情介绍,主演,标签,地区。关于BeautifulSoup的使用可以看这里BeautifulSoup技术文档 view plaincopy to clipboardprint?01.#抓取数据 02.def read_html(soup): 03. #解析出标题 04. html_title = soup.html.head.title.string 05. title = html_title[:len(html_title)-5] 06. #解析出电影介绍 07. try: 08. intro = soup.find('span',attrs={'class':'all hidden'}).text 09. except: 10. try: 11. node = soup.find('div',attrs={'class':'blank20'}).previousSibling 12. intro = node.contents[0]+node.contents[2] 13. except: 14. try: 15. contents = soup.find('div',attrs={'class':'blank20'}).previousSibling.previousSibling.text 16. 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. if len(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. pass 55. 56. #tag 57. tags = soup.find('div',attrs={'class':'blank20'}).findAll('a') 58. for tag_html in tags: 59. tag_str = tag_html.string 60. if len(tag_str) > 4: 61. continue 62. tag_list = Tag.objects.filter(name = tag_str) 63. if len(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. #except Exception.args: 74. # print "Could not download : %s" % args 75. print r'download success' 76. #抓取数据 def read_html(soup): #解析出标题 html_title = soup.html.head.title.string title = html_title[:len(html_title)-5] #解析出电影介绍 try: intro = soup.find('span',attrs={'class':'all hidden'}).text except: try: node = soup.find('div',attrs={'class':'blank20'}).previousSibling intro = node.contents[0]+node.contents[2] except: try: contents = soup.find('div',attrs={'class':'blank20'}).previousSibling.previousSibling.text intro = 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) if len(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 #tag tags = soup.find('div',attrs={'class':'blank20'}).findAll('a') for tag_html in tags: tag_str = tag_html.string if len(tag_str) > 4: continue tag_list = Tag.objects.filter(name = tag_str) if len(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: #except Exception.args: # print "Could not download : %s" % args print r'download success' 豆瓣的电影页面并不是很对称,所以有时候抓取的结果可能会有点出入 本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/Java2King/archive/2010/03/15/5378951.aspx 爬Google的查询页 最近没有没有Google API key了,因此只能自己将查询对应的URL准备好,然后通过脚本将该链接对应的网页爬下来。我们假定,我们要爬这样一个页面: http://www.google.com/search?q=IBM 我们可以直接在浏览器输入上面的URL,可以看到,是Google对应IBM这个查询的返回页。我们现在的目的是通过python程序把这个返回页download下来,存在本地,为后面的工作准备数据。 一下就是我的代码: import urllib2 , urlparse , gzip from StringIO import StringIO USER_AGENT = 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727; CIBA; InfoPath.2; 360SE)' class SmartRedirectHandler(urllib2.HTTPRedirectHandler): def http_error_301(self , req , fp , code , msg , headers): result = urllib2.HTTPRedirectHandler.http_error_301( self , req , fp , code , msg , headers) result.status = code return result def http_error_302(self , req , fp , code , msg , headers): result = urllib2.HTTPRedirectHandler.http_error_302( self , req , fp , code , msg , headers) result.status = code return result class DefaultErrorHandler(urllib2.HTTPDefaultErrorHandler): def http_error_default(self , req , fp , code , msg , headers): result = urllib2.HTTPError(req.get_full_url() , code , msg , headers , fp) result.status = code return result def openAnything(source , etag = None , lastmodified = None , agent= USER_AGENT): if hasattr(source , 'read'): return source if source == '-' : return sys.stdin if urlparse.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') if etag : request.add_header('If-None-Match', etag) if lastmodified : 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()) return opener.open(request) try : return open(source) except (IOError , OSError) : pass return StringIO(str(sources)) def fetch(source , etag = None , last_modified = None , agent =USER_AGENT): result = {} f = openAnything(source , etag , last_modified , agent) result['data'] = f.read() if hasattr(f , 'headers'): result['etag'] = f.headers.get('ETag') result['lastmodified'] = f.headers.get('Last-Modified') if f.headers.get('content-encoding' , '')=='gzip' : result['date']=gzip.GzipFile(fileobj = StringIO(result['data']) ).read() if hasattr(f , 'url') : result['url'] = f.url result['status'] = 200 if hasattr(f , 'status') : result['status'] = f.status f.close() return result if __name__=='__main__' : result = fetch("http://www.google.com/search?q=IBM") print result['data'] print result['url'] print result['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.import urllib.request 4.import xml.dom.minidom 5.import sqlite3 6.import threading 7.import time 8.9.class logger(object): 10. def log(self,*msg): 11. for i in msg: 12. print(i) 13.14.Log = logger() 15.Log.log('测试下') 16.17.class downloader(object): 18. 19. def __init__(self,url): 20. self.url = url 21. 22. def download(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.class parser(object): 37. 38. def __init__(self,content): 39. #获得根节点40. self.html = xml.dom.minidom.parseString(content) 41. 42. def parse(self): 43. Log.log('开始提取数据') 44. contents = {'content':'','url':[]} 45. #获得div节点46. divs = self.html.getElementsByTagName('div') 47. #获得content节点48. for div in divs: 49. if div.hasAttribute('class') and \ 50. div.getAttribute('class') == 'content': 51. #获得糗事百科的内容52. textNode = div.childNodes[0] 53. qContent = textNode.data 54. #数据填充55. contents['content'] = qContent 56. 57. #获得上一糗事、下一糗事节点58. spans = self.html.getElementsByTagName('span') 59. for span in spans: 60. pspan = span.parentNode 61. if pspan.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.def downloadPage(qid,db): 71. url = 'http://www.qiushibaike.com/articles/'+str(qid)+'.htm'72. content = downloader(url).download() 73. if content: 74. contents = parser(content).parse() 75. if contents['content']: 76. db.updateContent(qid,contents['content']) 77. for i in contents['url']: 78. db.addQID(i) 79. if len(contents['url']) == 2: 80. db.updateStatus(qid,2) 81.82.#下载池,表示同时允许下载的链接个数83.class downloaderPool(object): 84. def __init__(self,maxLength=15): 85. self.downloaders = [None]*maxLength 86. self.downloadList = [] 87. self.db = None88. 89. def setDownloadList(self,downloadList): 90. self.downloadList = list(set(self.downloadList+downloadList)) 91. 92. def setdb(self,db): 93. self.db = db 94. 95. def daemon(self): 96. #每隔一秒查询线程的状态,为非活动线程则设置为None97. Log.log('设置守护进程') 98. for index,downloader in enumerate(self.downloaders): 99. if downloader: 100. if not downloader.isAlive(): 101. Log.log('将下载器置空',index) 102. self.downloaders[index] = None103. 104. #检查线程池状态105. for index,downloader in enumerate(self.downloaders): 106. if not downloader: 107. qid = self.getQID() 108. if qid: 109. #创建线程110. t = threading.Thread(target=downloadPage,args=(qid,self.db)) 111. self.downloaders[index] = t 112. t.start() 113. t.join() 114. Log.log('设置下载器',index) 115. #间隔一秒执行一次116. time.sleep(1) 117. 118. def getQID(self): 119. try: 120. tmp = self.downloadList[0] 121. del self.downloadList[0] 122. return(tmp) 123. except: 124. return(None) 125. 126. def beginDownload(self): 127. #创建守护线程128. daemon = threading.Thread(target=self.daemon) 129. daemon.setDaemon(True) 130. daemon.start() 131. daemon.join() 132. 133. def getDownloader(self): 134. for index,downloader in enumerate(self.downloaders): 135. if not downloader: 136. return(index) 137. return(None) 138.139.140.ADD_Q_ID = 'insert into qiushibaike(id,success) values(?,?)'141.UPDATE_Q_CONTENT = 'update qiushibaike set content=? where id=?'142.UPDATE_Q_STATUS = 'update qiushibaike set success=? where id=?'143.Q_LIST = 'select id from qiushibaike where success=?'144.Q_LIST_BY_ID = 'select count(*) from qiushibaike where id=?'145.class dbConnect(object): 146. """ 147. create table qiushibaike( 148. id,Integer 149. content,Varchar 150. success,Interger 151. ) 152. #id表示糗事的ID 153. #content表示糗事的内容 154. #success表示是否下载成功,当该糗事内容下载完成,且获得上一页、下一页ID时表示下载完成 155. 1表示未完成 156. 2表示完成 157. """158. def __init__(self,dbpath='db.sqlite'): 159. self.dbpath = dbpath 160. 161. def addQID(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. def updateContent(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. def updateStatus(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. def getList(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. for i in rows: 217. l.append(i[0]) 218. #关闭连接219. c.close() 220. cn.close() 221. 222. Log.log('获得列表成功') 223. return(l) 224.225.class singleDownloader(object): 226. def __init__(self): 227. self.downloadList = [] 228. 229. def setdb(self,db): 230. self.db = db 231. 232. def setDownloadList(self,downloadList): 233. self.downloadList = list(set(self.downloadList+downloadList)) 234. 235. def beginDownload(self): 236. for i in self.downloadList: 237. downloadPage(i,self.db) 238. 239.def main(): 240. db = dbConnect('db.sqlite') 241. #dp = downloaderPool()242. #dp.setdb(db)243. sp = singleDownloader() 244. sp.setdb(db) 245. 246. dp=sp 247. 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/python import libxml2, libxslt class compoundXML: def __init__(self): self._result = None self._xsl = None self._xml = None def do(self, xml_file_name, xsl_file_name): self._xml = libxml2.parseFile(xml_file_name) if self._xml == None: return 0 styledoc = libxml2.parseFile(xsl_file_name) if styledoc == None: return 0 self._xsl = libxslt.parseStylesheetDoc(styledoc) if self._xsl == None: return 0 self._result = self._xsl.applyStylesheet(self._xml, None) def get_xml_doc(self): return self._result def get_translated(self): return self._result.serialize('UTF-8') def save_translated(self, file_name): self._xsl.saveResultToFilename(file_name, self._result, 0) def release(self): ''' this function must be called in the end. ''' self._xsl.freeStylesheet() self._xml.freeDoc() self._result.freeDoc() self._xsl = None self._xml = None self._result = None if __name__ == '__main__': test = compoundXML() test.do('test/testxmlutil.xml', 'test/testxmlutil.xsl') print test.get_translated() test.save_translated('test/testxmlutil.htm') test.release() 本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/zhaoweikid/archive/2004/08/14/74837.aspx 用python下载网页,超级简单! from urllib import urlopen webdata = urlopen("http://www.pythonid.com").read() print webdata 够简单吧,哈哈。 我来补充点,你那只能说是查看网页,怎能说是下载呢,总得如存吧 import urllib webfile = 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句: from urllib import urlretrieve urlretrieve('http://www.python.org', 'f:\\python_webpage.html') 用python下载网页,超级简单! 查看 from urllib import urlopen webdata = urlopen("http://www.pythonid.com").read() print webdata --------------- 下载并保存 import urllib webfile = 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 # down html from zm and save html to txt #   -*- coding:utf-8 -*- import htmllib, formatter, urllib, re website = '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 += date f = urllib.urlopen(website) p = htmllib.HTMLParser(formatter.NullFormatter()) p.feed(f.read()) p.close() seen = set() for url in p.anchorlist: if url[-3::] == 'asp':    if url in seen: continue    seen.add(url) urls=list(seen) k=len(urls) doc=open(u'南方周末'.encode('gb18030')+date+'.txt','a') for l, url in enumerate(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('\n',content)+'\n------------\n') print l+1,'-->',k doc.close() print u'下载结束' 把百度空间的文章下载为html /*作者:youstar http://www.youstar.org.ru 转载注明原创*/ 0x1    本文借鉴网上的代码加以修改实现了一个可以把百度空间的文章下载为html的功能,相对而言还有很多功能需要添加。编程使用的语言是python,越来越喜欢这脚本了,感觉在处理很多事情上很方便,其中调用一些lib和函数,看代码的时候也学到了一些函数的使用。 0x2 #! /usr/bin/env python #coding=utf-8 import urllib2 import re import sys import os pattern = "" reg_tail = "" username = "" def downURL(url, filename):     print "Download %s, save as %s"%(url, filename)     try:         fp = urllib2.urlopen(url)     except:         print "download exception"         return 0     paths = os.getcwd()+username+'/'+filename     op = open(paths, "wb")     while 1:         s = fp.read()         if not s:             break         op.write(s)     fp.close( )     op.close( )     return 1 def getURL(url):     print "Parsing %s"%url     try:         fp = urllib2.urlopen(url)         contents = fp.readlines()     except:         print "exception"         return []     item_list = []     for s in contents:         urls = pattern.findall(s)         if urls:             item_list.extend(urls)         fp.close( )     return item_list def CreateDirectory():     if not os.path.exists(os.getcwd()+username):          os.mkdir(os.getcwd()+username)          print 'step 2:Create Directory Success!'     else:          print 'step 2:Directory has existed!' def reptile(base_url):     """     Download all articles from base_url.     Arguments:     - `base_url`: Url of website.     """     page_list = []     base_page = base_url.rstrip("/")+"/blog/index/"     sign_tail = u"尾页"     tail = ""     total_page = 10     global username     print 'step 3:Number of index'     try:         fp = urllib2.urlopen(base_page+"0")     except:         print "%s: Not such url"%page         print sys.exc_info()     else:         for s in fp.readlines():             if sign_tail in s.decode("gbk"):                 tail = s.decode("gbk")                 break         fp.close()     if tail:         pos = tail.rfind(u"尾页")         total_page =int(tail[:pos-3].split("/")[-1])     output_list = [ ]     for idx in range(total_page+1):         item_page = "%s%d"%(base_page, idx)         item_list = getURL(item_page)         if item_list:             output_list.extend(item_list)         print 'step 4:Down pages!'     item_list = list(set(output_list))     for item in item_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 "step 5:Total: %d articles."%(len(item_list))     print "Congratulations"     pass if __name__ == '__main__':     if len(sys.argv) != 2:         print "Usage: %s url of baidu space"%sys.argv[0]         print "Such as: %s http://hi.baidu.com/Username"         sys.exit(1)     base_url = sys.argv[1]     if not base_url.startswith("http://hi.baidu.com/"):         print "Wrong Type of URL??", "It works on Baidu Space only."         sys.exit(1) username = base_url.rstrip("/").split("/")[-1]     print ('step 1:'+username)     C reateDirectory()     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进行网页分析实现批量下载(final version) 转自: http://www.builder.com.cn/2008/0517/867087.shtml start.bat        //make the dir for files and run the project          mkdir files         python CustomParser.py CustomParser.py from sgmllib import SGMLParser from string import find, replace, rjust from threading import Thread import urllib __author__ = "Chen Peng (peng.ch@hotmail.com)" __version__ = "$Revision: 1.0 $" __date__ = "$Date: 2006/03/03 $" __copyright__ = "Copyright (c) 2006 Chen Peng" __license__ = "Python" __all__ = ["Gif_163_Parser"] class PDownloadThread( Thread ):     """     Download the files in the dict and save them to local files with the given name     """     def __init__( self, DictList,i ):         Thread.__init__( self )         self.DictList=DictList         self.pageno=str(i);        def run( self ):             for k in self.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 'Save to file '+k        class Gif_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    """    def reset( self ):                                      SGMLParser.reset( self )          self.headURL='http://mmsimg.163.com/new_web/loaditem.jsp/type=1/path='         self.SubURL = []         self.Links = {}              def start_script( self, attrs ):         #self.SubURL.extend( [' %s="%s"' % ( key, value ) for key, value in attrs] )         pass    def end_script( self ):         pass       def handle_data( self, text ):         if find( text, 'showPic' )!=-1:            self.Links[replace( text.split( 'n' )[1], 'xc3xfbxd7xd6: ', '' )]=self.headURL+replace ( text.split( ',' )[2], ''', '' );                def Execute( self ):          for i in range( 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()                except IOError:                pass            #print ( ["%s=%sn"% ( k, self.Links[k] ) for k in self.Links.keys()] )         #print self.Links if __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-*- ''' Created on 2009-9-7 @author: Ken ''' import  urllib import urllib2 import random import os from sgmllib import SGMLParser class URLLister(SGMLParser): '''获取html中的图片地址\url地址,装入list中''' def reset(self): SGMLParser.reset(self) self.img = [] self.urls = [] def start_img(self, attrs): img = [v for k, v in attrs if k=='src'] if img: self.img.extend(img) def start_a(self, attrs): href = [v for k, v in attrs if k=='href'] if href: self.urls.extend(href) def get_docum(url): url=url+'//' sock=urllib.urlopen(url) file=sock.read() sock.close() return file def is_img(url): global imglenth request=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'])#判断图片大小 if Length>imglenth: return Type else: return 0 except: print '该图片无法在服务器找到或者图片地址无法识别!' print url def get_file_name(ospath,imgname): name = 'P'+str(random.randint(10000000,99999999)) filepath = "%s%s.%s" % (ospath,name,(imgname.split('.'))[-1]) return filepath                def get_img(rq): parser = URLLister();    doc=get_docum(rq);    parser.feed(doc);    img = parser.img parser.close() for i in range(0,len(img)): if img[i][0:4]!='http':#处理绝对路径 img[i]=rq+img[i] return img def get_url(rq): parser = URLLister();    doc=get_docum(rq);    parser.feed(doc);    urls = parser.urls parser.close() for i in range(0,len(urls)): if urls[i][0:4] != 'http': #处理绝对路径 urls[i] = rq+urls[i] return urls def depth(url,dep,ospath): '''三个参数分别是 url : 需要下载的网站地址 dep :需要遍历的深度 ospath:图片下载的本地文件夹     ''' global num if dep<=0: return 0 else: img=get_img(url) for j in range(0,len(img)): if is_img(img[j]) == 'image': isExist = True; while(isExist): #判断文件是否已经存在 filepath = get_file_name(ospath,img[j]); if (not os.path.exists(filepath)): isExist = False; try: urllib.urlretrieve(img[j], filepath) print '已经下载好第%d张图片'%(num+1) num+=1 except: print '该图片无法下载或者图片地址无法识别!' print img[j] else: pass urls=get_url(url) if len(urls)>0: for url in urls: depth(url,dep-1,ospath) else: return 0 return 1 if __name__ == '__main__': imglenth = 1           #设置需要下载的图片大小。 num=0 depth('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中的所有链接: from HTMLParser import HTMLParser   class MyHTMLParser(HTMLParser): def __init__(self): HTMLParser.__init__(self) self.links = []   def handle_starttag(self, tag, attrs): #print "Encountered the beginning of a %s tag" % tag if tag == "a": if len(attrs) == 0: pass else: for (variable, value) in attrs: if variable == "href": self.links.append(value)   if __name__ == "__main__": html_code = """ google.com PythonClub Sina """ 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模块可用以输出格式化的文本。嗯,实现的顶层函数如下: def extract_text(html): # Derive from formatter.AbstractWriter to store paragraphs. writer = LineWriter() # Default formatter sends commands to our writer. formatter = AbstractFormatter(writer) # Derive from htmllib.HTMLParser to track parsed bytes. parser = TrackingParser(writer, formatter) # Give the parser the raw HTML data. parser.feed(html) parser.close() # Filter the paragraphs stored and output them. return writer.output() TrackingParser覆盖了解析标签开始和结束时调用的回调函数,用以给缓冲对象传递当前解析的索引。通常你不得不这样,除非你使用不被推荐的方法——深入调用堆栈去获取执行帧。这个类看起来是这样的: class TrackingParser(htmllib.HTMLParser): """Try to keep accurate pointer of parsing location.""" def __init__(self, writer, *args): htmllib.HTMLParser.__init__(self, *args) self.writer = writer def parse_starttag(self, i): index = htmllib.HTMLParser.parse_starttag(self, i) self.writer.index = index return index def parse_endtag(self, i): self.writer.index = i return htmllib.HTMLParser.parse_endtag(self, i) LinWriter的大部分工作都通过调用formatter来完成。如果你要改进或者修改程序,大部分时候其实就是在修改它。我们将在后面讲述怎么为它加上机器学习代码。但你也可以保持它的简单实现,仍然可以得到一个好结果。具体的代码如下: class Paragraph: def __init__(self): self.text = '' self.bytes = 0 self.density = 0.0 class LineWriter(formatter.AbstractWriter): def __init__(self, *args): self.last_index = 0 self.lines = [Paragraph()] formatter.AbstractWriter.__init__(self) def send_flowing_data(self, data): # Work out the length of this text chunk. t = len(data) # We've parsed more text, so increment index. self.index += t # Calculate the number of bytes since last time. b = self.index - self.last_index self.last_index = self.index # Accumulate this information in current line. l = self.lines[-1] l.text += data l.bytes += b def send_paragraph(self, blankline): """Create a new paragraph if necessary.""" if self.lines[-1].text == '': return self.lines[-1].text += 'n' * (blankline+1) self.lines[-1].bytes += 2 * (blankline+1) self.lines.append(Writer.Paragraph()) def send_literal_data(self, data): self.send_flowing_data(data) def send_line_break(self): self.send_paragraph(0) 这里代码还没有做输出部分,它只是聚合数据。现在我们有一系列的文字段(用数组保存),以及它们的长度和生成它们所需要的HTML的大概字节数。现在让我们来看看统计学带来了什么。 数据分析 幸运的是,数据里总是存在一些模式。从下面的原始输出你可以发现有些文本需要大量的HTML来编码,特别是标题、侧边栏、页眉和页脚。 虽然HTML字节数的峰值多次出现,但大部分仍然低于平均值;我们也可以看到在大部分低HTML字节数的字段中,文本输出却相当高。通过计算文本与HTML字节数的比率(即密度)可以让我们更容易明白它们之间的关系: 密度值图更加清晰地表达了正文的密度更高,这是我们的工作的事实依据。 过滤文本行 过滤文本行的最简单方法是通过与一个阈值(如50%或者平均值)比较密度值。下面来完成LineWriter类: def compute_density(self): """Calculate the density for each line, and the average.""" total = 0.0 for l in self.lines: l.density = len(l.text) / float(l.bytes) total += l.density # Store for optional use by the neural network. self.average = total / float(len(self.lines)) def output(self): """Return a string with the useless lines filtered out.""" self.compute_density() output = StringIO.StringIO() for l in self.lines: # Check density against threshold. # Custom filter extensions go here. if l.density > 0.5: output.write(l.text) return output.getvalue() 这个粗糙的过滤器能够获取大部分正确的文本行。只要页眉、页脚和侧边栏文本并不非常长,那么所有的这些都会被剔除。然而,它仍然会输出比较长的版本声明、注释和对其它故事的概述;在图片和广告周边的比较短小的文本,却被过滤掉了。要解决这个问题,我们需要更复杂些的启发式过滤器。为了节省手工计算需要花费的无数时间,我们将利用机器学习来处理每一文本行的信息,以找出对我们有用的模式。 监督式机器学习 这是一个标识文本行是否为正文的接口界面:所谓的监督式学习就是为算法提供学习的例子。在这个案例中,我们给定一系列已经由人标识好的文档——我们知道哪一行必须输出或者过滤掉。我们用使用一个简单的神经网络作为感知器,它接受浮点输入并通过“神经元”间的加权连接过滤信息,然后输后另一个浮点数。大体来说,神经元数量和层数将影响获取最优解的能力。我们的原型将分别使用单层感知器(SLP)和多层感知器(MLP)模型。我们需要找些数据来供机器学习。之前的LineWriter.output()函数正好派上用场,它使我们能够一次处理所有文本行并作出决定哪些文本行应该输出的全局结策。从直觉和经验中我们发现下面的几条原则可用于决定如何过滤文本行: · 当前行的密度 · 当前行的HTML字节数 · 当前行的输出文本长度 · 前一行的这三个值 · 后一行的这三个值 我们可以利用FANN的Python接口来实现,FANN是Fast Artificial Neural NetWork库的简称。基本的学习代码如下: from pyfann import fann, libfann # This creates a new single-layer perceptron with 1 output and 3 inputs. obj = libfann.fann_create_standard_array(2, (3, 1)) ann = fann.fann_class(obj) # Load the data we described above. patterns = fann.read_train_from_file('training.txt') ann.train_on_data(patterns, 1000, 1, 0.0) # Then test it with different data. for datin, datout in validation_data: result = ann.run(datin) print 'Got:', result, ' Expected:', datout 尝试不同的数据和不同的网络结构是比较机械的过程。不要使用太多的神经元和使用太好的文本集合来训练(过拟合),相反地应当尝试解决足够多的问题。使用不同的行数(1L-3L)和每一行不同的属性(1A-3A)得到的结果如下: 有趣的是作为一个猜测的固定阈值,0.5的表现非常好(看第一列)。学习算法并不能仅仅通过比较密度来找出更佳的方案(第二列)。使用三个属性,下一个 SLP比前两都好,但它引入了更多的假阴性。使用多行文本也增进了性能(第四列),最后使用更复杂的神经网络结构比所有的结果都要更好,在文本行过滤中减少了80%错误。注意:你能够调整误差计算,以给假阳性比假阴性更多的惩罚(宁缺勿滥的策略)。 结论 从任意HTML文件中抽取正文无需编写针对文件编写特定的抽取程序,使用统计学就能获得令人惊讶的效果,而机器学习能让它做得更好。通过调整阈值,你能够避免出现鱼目混珠的情况。它的表现相当好,因为在神经网络判断错误的地方,甚至人类也难以判定它是否为正文。现在需要思考的问题是用这些“干净”的正文内容做什么应用好呢? 解析网页内容的好代码 from sgmllib import SGMLParser import urllib class 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 url python模块之HTMLParser: 解析html,获取url HTMLParser是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 -*- import HTMLParser class MyParser(HTMLParser.HTMLParser): def __init__(self): HTMLParser.HTMLParser.__init__(self) def handle_starttag(self, tag, attrs): # 这里重新定义了处理开始标签的函数 if tag == 'a': # 判断标签的属性 for name,value in attrs: if name == 'href': print value if __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 文档的时候,这项功能是非常方便的。   import urlparse   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基地址以字符/结尾。   下面是上面几个函数的详细一点的用法举例: import urlparse   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")   print parsedTuple   #将组件反解析成URL   print "\反解析python文档页面的URL"   unparsedURL = urlparse.urlunparse( \   (URLscheme, URLlocation, URLpath, '', '', ''))   print "\t" + unparsedURL    #将路径和新文件组成一个新的URL   print "\n利用拼接方式添加更多python文档页面的URL"   for mod in modList:   newURL = urlparse.urljoin(unparsedURL, \   "module-%s.html" % (mod))   print "\t" + newURL   #通过为路径添加一个子路径来组成一个新的URL   print "\n通过拼接子路径来生成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-ur llib2/request-objects.html   二、打开HTML文档   上面介绍了如何解析页面的URL,现在开始讲解如何通过URL打开一个网页。实际上,Python所带的urllib和urllib2这两个模块为我们提供了从URL打开并获取数据的功能,当然,这包括HTML文档。   import urllib   u = urllib.urlopen(webURL)   u = urllib.urlopen(localURL)   buffer = u.read()   print u.info()   print "从%s读取了%d 字节数据.\n" % (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位置有关的元数据,比如内容长度、内容类型,等等。下面通过一个较为详细的例子来对这些函数进行说明。   import urllib   webURL = "http://www.python.org"   localURL = "index.html"    #通过URL打开远程页面   u = urllib.urlopen(webURL)   buffer = u.read()   print u.info()   print "从%s读取了%d 字节数据.\n" % (u.geturl(),len(buffer) )   #通过URL打开本地页面   u = urllib.urlopen(localURL)   buffer = u.read()   print u.info()   print "从%s读取了%d 字节数据.\n" % (u.geturl(),len(buffer) )   上面代码的运行结果如下所示:   Date: Fri, 26 Jun 2009 10:22:11 GMT   Server: Apache/2.2.9 (Debian) DAV/2 SVN/1.5.1 mod_ssl/2.2.9 OpenSSL/0.9.8g mod_wsgi/2.3 Python/2.5.2   Last-Modified: Thu, 25 Jun 2009 09:44:54 GMT   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, 26 Jun 2009 10:16:10 GMT   从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是最常用的模块之一。   import HTMLParser   import urllib   class parseLinks(HTMLParser.HTMLParser):   def handle_starttag(self, tag, attrs):   if tag == 'a':   for name,value in attrs:   if name == 'href':    print value   print self.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文件很大,需要分段发送给解析器的时候,这个功能就会有用武之地了。下面是一个具体的例子   import HTMLParser   import urllib   import sys   #定义HTML解析器   class parseLinks(HTMLParser.HTMLParser):   def handle_starttag(self, tag, attrs):   if tag == 'a':   for name,value in attrs:   if name == 'href':   print value    print self.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属性值所指的文件。   import HTMLParser   import urllib   def getImage(addr):   u = urllib.urlopen(addr)   data = u.read()   class parseImages(HTMLParser.HTMLParser):   def handle_starttag(self, tag, attrs):   if tag == 'img':   for name,value in attrs:   if name == '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对象对数据进行相应的解析。下面是一个具体的示例:   import HTMLParser   import urllib   import sys   urlString = "http://www.python.org"   #把图像文件保存至硬盘   def getImage(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解析器   class parseImages(HTMLParser.HTMLParser):   def handle_starttag(self, tag, attrs):    if tag == 'img':   for name,value in attrs:   if name == 'src':   getImage(urlString + "/" + value)   #创建HTML解析器的实例   lParser = parseImages()   #打开HTML文件   u = urllib.urlopen(urlString)   print "Opening URL\n===================="   print u.info()   #把HTML文件传给解析器   lParser.feed(u.read())   lParser.close()   上述代码的运行结果如下所示:   Opening URL   ====================   Date: Fri, 26 Jun 2009 10:54:49 GMT   Server: Apache/2.2.9 (Debian) DAV/2 SVN/1.5.1 mod_ssl/2.2.9 OpenSSL/0.9.8g mod_wsgi/2.3 Python/2.5.2   Last-Modified: Thu, 25 Jun 2009 09:44:54 GMT   ETag: "105800d-46e7-46d29136f7180"   Accept-Ranges: bytes   Content-Length: 18151   Connection: close   Content-Type: text/html   Saving python-logo.gif   Saving trans.gif   Saving trans.gif   Saving afnic.fr.png 三、从HTML文档中提取文本   处理HTML文档的时候,我们常常需要从其中提取出所有的文本。使用HTMLParser模块后,这项任务将变得非常简单了。首先,我们需要定义一个新的HTMLParser类,以覆盖handle_data()方法,该方法是用来解析并文本数据的。   import HTMLParser   import urllib   class parseText(HTMLParser.HTMLParser):   def handle_data(self, data):   if data != '\n':   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文件很大,需要分段发送给解析器的时候,这个功能就会有用武之地了。下面是一个具体的代码示例:   import HTMLParser   import urllib   urlText = []   #定义HTML解析器   class parseText(HTMLParser.HTMLParser):   def handle_data(self, data):   if data != '\n':   urlText.append(data)   #创建HTML解析器的实例   lParser = parseText()   #把HTML文件传给解析器   lParser.feed(urllib.urlopen( \   “http://docs.python.org/lib/module-HTMLParser.html” \   ).read())   lParser.close()   for item in urlText:   print item   上面代码的运行输出过长,在此略过 四、从HTML文档中提取Cookies   很多时候,我们都需要处理Cookie,幸运的是Python语言的cookielib模块为我们提供了许多自动处理在HTML中的HTTP Cookie的类。当处理要求为客户端设置Cookie的HTML文档的时候,这些类对我们非常有用。   import urllib2   import cookielib   from urllib2 import urlopen, Request   cJar = cookielib.LWPCookieJar()   opener=urllib2.build_opener( \   urllib2.HTTPCookieProcessor(cJar))   urllib2.install_opener(opener)   r = Request(testURL)   h = urlopen(r)   for ind, cookie in enumerate(cJar):   print "%d - %s" % (ind, cookie)   cJar.save(cookieFile)   为了从HTML文档提取cookies,首先得使用cookielib模块的LWPCookieJar()函数创建一个cookie jar的实例。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)函数了。   import os   import urllib2   import cookielib   from urllib2 import urlopen, Request   cookieFile = "cookies.dat"   testURL = 'http://maps.google.com/'   #为cookie jar 创建实例   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 "页面的头部\n======================"   print h.info()   print "页面的Cookies\n======================"   for ind, cookie in enumerate(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-2011 11:26:48 GMT; path=/; domain=.google.com   Date: Fri, 26 Jun 2009 11:26:48 GMT   Server: mfe   Expires: Fri, 26 Jun 2009 11:26:48 GMT   Transfer-Encoding: chunked   Connection: close   页面的Cookies   ======================   0 - 五、为HTML文档中的属性值添加引号   前面我们讨论了如果根据HTML解析器中的某种处理程序来解析HTML文件,可是有时候我们却需要使用所有的处理程序来处理HTML文档。值得庆幸的是,使用HTMLParser模块解析HTML文件的所有要素并不比处理链接或者图像难多少。   import HTMLParser    import urllib   class parseAttrs(HTMLParser.HTMLParser):   def handle_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对象对数据进行相应的解析。下面是一个具体的示例代码:   import HTMLParser   import urllib   import sys   #定义HTML解析器   class parseAttrs(HTMLParser.HTMLParser):   def init_parser (self):   self.pieces = []   def handle_starttag(self, tag, attrs):   fixedAttrs = ""   #for name,value in attrs:   for name, value in attrs:   fixedAttrs += "%s=\"%s\" " % (name, value)   self.pieces.append("<%s %s>" % (tag, fixedAttrs))   def handle_charref(self, name):   self.pieces.append("&#%s;" % (name))   def handle_endtag(self, tag):   self.pieces.append("" % (tag))   def handle_entityref(self, ref):   self.pieces.append("&%s" % (ref))   def handle_data(self, text):   self.pieces.append(text)    def handle_comment(self, text):   self.pieces.append("" % (text))   def handle_pi(self, text):   self.pieces.append("" % (text))   def handle_decl(self, text):   self.pieces.append("" % (text))   def parsed (self):   return "".join(self.pieces)   #创建HTML解析器的实例   attrParser = parseAttrs()   #初始化解析器数据   attrParser.init_parser()   #把HTML文件传给解析器   attrParser.feed(urllib.urlopen("test2.html").read())   #显示原来的文件内容   print "原来的文件\n========================"   print open("test2.html").read()   #显示解析后的文件   print "解析后的文件\n========================"   print attrParser.parsed()   attrParser.close()   我们还需要建立一个测试文件,名为test2.html,该文件内容可以从上述代码的运行结果看到,具体如下所示: 原来的文件 ======================== Web页面

Web页面清单

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

Web页面清单

Python网站 本地页面   六、小结 对搜索引擎、文件索引、文档转换、数据检索、站点备份或迁移等应用程序来说,经常用到对网页(即HTML文件)的解析处理。事实上,通过Python语言提供的各种模块,我们无需借助Web服务器或者Web浏览器就能够解析和处理HTML文档。本文将详细介绍了如何使用Python模块来迅速解析在HTML文件中的数据,从而处理特定的内容,如链接、图像和Cookie等。同时,我们还给出了一个规范HTML文件的格式标签的例子,希望本文对您会有所帮助。 Python读取网页并保存 代码如下: import sys import urllib2 import os print("Parameter count : " ,len(sys.argv)) if len(sys.argv) < 3:     print("Parameter required:")     print("SavingHttpPageTool.exe [WebPageAddress] [savingPath]")     exit(0) name = sys.argv[2] if os.path.exists(name):     print("remove file:" + name)     os.remove(name) print("get page:" + sys.argv[1]) req = urllib2.Request(sys.argv[1]) res = urllib2.urlopen( req ) ##headers = str(res.info()) ##print(headers) html=res.read() print("write file:" + name) writeFile = file(name,'w') writeFile.write(html) writeFile.close() print("finished") python 正则小试 读取网页内容 2个月前坛子里有道友问的shell问题,当时用python草草写下一个简单的脚本,今天无意中翻出贴出来已做备用 #!/usr/bin/env python # -*- coding : UTF-8 -*- # Author : wanghaoyu - wanghaoyu1625@gmail.com # QQ : 42030925 # Last modified : 2010-04-19 14:04 # Filename : web.py # Description : import os,urllib,urllib2 import re,sys url = "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) print cont 输出结果是:             运营时间:5:50-21:20             票价:上车2元,全程7元             往程:七十二区总站 - 金威啤酒厂 - 新福市场 - 宝城批发市场 - 宝安海关大厦 - 宝安党校 - 新安影剧院 - 恒丰商场 - 沁园公园 - 教育培训中心 - 恒丰中心 - 宝安税务局 - 宝安海雅百货 - 冠利达大厦 - 建安新村 - 北方公司 - 西乡路口 - 臣田 - 固戍 - 劲力集团 - 三围路口 - 中华商贸城 - 鹤洲路口 - 钟屋 - 翠湖花园 - 机场路口 - 下十围 - 白石厦 - 福永工业区 - 凤凰工业区 - 福永汽车站凤凰分站 - 上南油站 - 沙井电子城 - 上寮市场 -上南酒店 - 上寮市场 - 沙井天虹商场 - 万丰派出所 - 万丰工业区 - 马鞍山市场 - 茭塘工业区 - 大王山 - 三洋马达厂 - 沙一村 - 海欣花园 - 安托山科技园 - 海上田园风光 - 国富康总站             返程:国富康总站 - 海上田园风光 - 安托山科技园 - 海欣花园 - 沙一村 - 三洋马达厂 - 大王山 - 茭塘工业区 - 马鞍山市场 - 万丰工业区 - 万丰派出所 - 沙井天虹商场 - 上寮市场 - 沙井电子城 - 上南油站 - 福永汽车站凤凰分站 - 凤凰工业区 - 福永工业区 - 白石厦 - 下十围 - 机场路口 - 翠湖花园 - 钟屋 - 鹤洲路口 - 中华商贸城 - 三围路口 - 劲力集团 - 固戍 - 臣田 - 西乡路口 - 北方公司 - 建安新村 - 冠利达大厦 - 宝安海雅百货 - 宝安税务局 - 恒丰中心 - 教育培训中心 - 沁园公园 - 恒丰商场 - 新安影剧院 - 宝安党校 - 宝安海关大厦 - 宝城批发市场 - 新福市场 - 金威啤酒厂 - 七十二区总站 抓取網頁的最佳語言 : Python 最初 最早我用C/C++語言慢慢寫抓網頁的用它來抓網頁真的是程式,一開始甚至打算自己寫抓取網頁的函式庫,想說當做練習,可是HTTP協定 雖然不難,可是煩,要處理的細節太多了,後來受不了,轉而使用現成的Library : cUrl,但是C/C++語言開發這類東西的效率實在太慢了,我的程式不停的修改、不停的修改,光是編譯的時間就吃掉了不知道多少,字串的處理C/C++ 沒有內建正規表示法或一些好用的字串函數之類的,處理起來也礙手礙腳,當時,我想將我寫好的函數庫寫成能讓Lua呼叫的形式,或著甚是C/C++來呼叫Lua,因為C/C++有很多細節要處理,Memory leak有的沒有的雜事,我想要的只是專注在寫抓取網頁的程式,因此用Lua包裝似乎是不錯的選擇,但是開發時間太久了,事情一直沒有變好 直到 我下了一個結論,C/C++不適合寫抓取網頁的程式,我開始思考我需要什麼,我想我既然要包裝成其它語言將細節藏起來,為何不直接使用script語言? 我最早一直擔心的是效率的問題,但是到後來想想反正真正沒效率的部份包給C/C++去做事實上沒有太大的差別,而且又有動態語言的彈性、除錯上的方便等等好處,何樂不為? 於是我開始尋找一款合適的語言 Perl 如何? 很早以前我有用Perl寫過一些CGI程式、留言版、網站管理系統、文章管理系統等等,有人說Perl是只能寫一次的語言,它有很多很簡短的符號所構成的表示法,可讀性不是很好,模組化設計也沒有非常好的支援,OO也是一樣,新版的Perl遲遲沒有推出,似乎已經有點變成遺產的感覺,或許是上面的理由還是偏見,總而言之我不喜歡Perl PHP? 做為一個以網頁為主要用途的語言,拿來當做其它用途總有種不太合適的感覺,從它的語法來看,很明顯是參考C語言、Perl等等而來的,但是卻沒有加以改進,我個人認為它可能沒有預料到PHP居然會紅成這樣,變成網頁程式設計的主流語言,後來有很多缺點就變得顯而易見,不夠嚴僅的語法、不夠好的模組化設計、不良的OO支援、容易寫出安全性有問題的程式等等,命名空間也是它一大缺點之一,光是看到一大堆前綴字開頭的函數就有種倒胃口的感覺,有人說 PHP is the BASIC of the 21st century 在這個影片裡,總合種種理由,做為抓取網頁的用途,PHP出局 Lua Lua做為輕量級的語言相當的優秀,可是你不會想用Lua來寫大型的程式,我也不會想這麼做,它語言的設計都是以速度為優先考量,寫起來並不怎麼順手的感覺,再加上目前的資源不多,可能很多東西都得自行包裝,這樣就和我原先想做的事是一樣的,因此不考慮Lua Java Java是和網路一起成長的程式語言,做為抓取網頁的用途,它絕對有能力勝任,但是…,我嫌它太囉唆了,還有太癡肥,當一款語言太囉唆和太癡肥往往會令人討厭,歐! 想到Java我就想起eclipse在我那台只有256扣掉分給顯示記憶體的筆電上執行的情況,讓我想把電腦砸掉,不好意思,我不喜歡Java 在前面的影片裡的老兄一樣也有提到,有興趣可以看看 Java is the COBOL of the 21st century Python 最後,我在PTT的程式設計討論版上描述了我的需求,有人推文說 Python,我抓了抓頭髮,Python? WTF? 這是什麼? 我從來沒有聽過這款語言,於是上網找了一下資料,和問了一些問題,發現這款語言正是我想要的,它很容易被擴充,因此效能不足可以用C/C++補強,你想得到的函式庫幾乎都已經有人寫好了,光從下載網頁這件工作來看,它的標準函式庫已經有了這樣的功能,你覺得不夠好還有其它很多的選擇,開箱即用的哲學,讓安裝函式庫非常簡單,不像C/C++的編譯惡夢讓你抓光頭髮,而它最優秀的地方之一就是它的可讀性,寫起來相當順手、優雅,讀起來也一樣順眼,重要的是很有趣,那麼開發大型的程式呢? script語言常見的問題就是對於開發大型程式來說很不適合,但是Python卻不是如此,良好的OO、模組化等等它都有良好的支援,再加上Google也是Python的愛用者,YouTube也是用Python開發的,有了這些大咖背書,證明這款語言的確是相當優秀,在決定使用Python之後我就立刻訂購了一本Learning Python,開始學習Python 愛上Python Python並沒有讓我失望,能用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來抓取網頁,它是以容錯著名的HTML Parser,但是,它的效率很差,又或著說,找到目標HTML標籤的方式很沒效率,一般都用find等方式來找到所要的標籤 soup.find('div', dict(id='content')) 它真的很沒效率,當你抓取大一點的網頁時,多塞幾個一起抓和解析,你就會看見你的CPU使用率永遠是滿的狀態,原本我預計抓網頁的瓶頸都會落在網路IO上面,但是用它來抓取網頁卻超出我預料,沒想到它會這麼吃重,於是沒辦法,我開始尋找更好的選擇 lxml 我找到一個Blog的文章 : Python HTML Parser Performance,介紹了Python各種Parser的效能,效能最亮眼的,就是lxml,我最初擔心的是找到資料標籤會不會很困難,但是我發現它支援xpath,就試著改寫原本BeautifulSoup用find等等函數寫的尋找標籤程式,發現xpath遠比那種方式來得好用太多了,而且效率好太多了,BeautifulSoup的find極度的沒有效率,大部份的CPU時間都耗在一堆find函數走訪HTML樹上,而xpath篩選標籤的方式來得有效率多了,以下舉幾個我實際用在抓取網頁的案子中的例子 def getNextPageLink(self, tree): """Get next page link   @param tree: tree to get link @return: Return url of next page, if there is no next page, return None """ paging = tree.xpath("//span[@class='paging']") if paging: links = paging[0].xpath("./a[(text(), '%s')]" % self.localText['next']) if links: return str(links[0].get('href')) return None listPrice = tree.xpath("//*[@class='priceBlockLabel']/following-sibling::*") if listPrice: detail['listPrice'] = self.stripMoney(listPrice[0].text) 原本使用BeautifulSoup在尋找標籤遇到麻煩的走訪羅輯上的問題還得寫程式解決,xpath本身就有豐富的語法可以提供各種篩選的條件,羅輯從程式碼被移到了xpath語法上,有了這樣的語法,尋找目標標籤輕鬆了許多,而且效率也很好,從此我就和BeautifulSoup說再見,改用lxml來找標籤 配合FireFox的工具 如果有一些工具可以幫助寫解析網頁的程式該有多好,這也是我希望能有的,使用了xpath之後,我找到了FireFox的插件,XPath checker等xpath的工具,可以先用它來確定抓到的元素是正確的,然後FireBug在檢視網頁結構上也有很大的幫助 FireFox插件XPath checker畫面 使用FireBug檢視網頁元素 結論 就目前一路走過來的經驗來看,抓取網頁Python的確是最佳的選擇,不過我們到目前為止我們都只討論到工具,事實上還有設計上的問題要解決,留在下一次寫 Python读取网页并保存(转) http://houzhengqing.blog.163.com/blog/static/22754987200982813739833/ 代码如下: import sys import urllib2 import os print("Parameter count : " ,len(sys.argv)) if len(sys.argv) < 3:     print("Parameter required:")     print("SavingHttpPageTool.exe [WebPageAddress] [savingPath]")     exit(0) name = sys.argv[2] if os.path.exists(name):     print("remove file:" + name)     os.remove(name) print("get page:" + sys.argv[1]) req = urllib2.Request(sys.argv[1]) res = urllib2.urlopen( req ) ##headers = str(res.info()) ##print(headers) html=res.read() print("write file:" + name) writeFile = file(name,'w') writeFile.write(html) writeFile.close() print("finished") 用Python读取网页 最近信号处理与机器翻译课要交作业,其中一项是网页采集器,又称spider。爬虫从一个或若干初始网页的URL开始,获得初始网页上的URL,在抓取网 页的过程中,不断从当前页面上抽取新的URL放入队列,直到满足系统的一定停止条件。Python很适合这类与网络有关的工作。下了个Phthon 2.5,居然自带Python Manuals,连借书都免了。 只看Manuals大概就明白了。因为有好多功能健全的lib,用Python抓取网页是如此简单:    import urllib                        urlItem = urllib.urlopen("http://www.baidu.com")     htmSource = urlItem.read()     urlItem.close() 显示网页的内容:    print htmSource 显示的是html文件内容。 我在VC里用这个来实现的:CInternetSession session,这是MFC封装的 CInternetSession session; //建立一个Internet会话 CInternetFile* file=NULL; CString m_buffer; try { file=(CInternetFile*)session.OpenURL(url); } catch(CInternetException* pEx) { file=NULL;pEx->Delete(); } if(file){ CString line; for(int i=0; file->ReadString(line); i++){ m_buffer += line+"\r\n"; } file->Close(); delete file; } 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:\temp\1.jpg")   网页抓取实际上分为2步:第一步是发出请求,第二步接收服务器返回的数据,在Python中也是这么做的. POST方式: 01.import urllib.parse   02.import urllib.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.import urllib.parse   02.import urllib.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/env python import urllib2 # change followings before use user = 'foo' passwd = 'bar' proxyserver = '1.2.3.4:5' url   = 'http://www.google.com/' def proxy1():     # 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)     print sContent.read() def proxy2():     # work for someone, but not for me     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)     print sContent.read() def proxy3():     # work for someone, but not for me     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)     print sContent.read()  在linux系统中,如果urllib2设置的代理不好用可以试试环境变量: export http_proxy='protocol://user:passwd@proxyserver:port' export https_proxy='protocol://user:passwd@proxyserver:port'  比如通过代理上传appengine文件,其SDK中的rpc不提供代理设置,就可以用这招。 python访问网页带cookie问题 我现在要用python访问一个网站的网页,取得一些信息 但是网站要求先登录,然后才能继续访问,登录过程就是写了个cookie 请问下python访问网页怎么保持住cookie呢? 我用的是python3.1,只有urllib和http两个库了 网上找了一些代码,都是python2.x版本的 哪位好心的兄弟写几句python3.1的代码,感激不尽 在 http header中加入Cookie 即可,参考下列代码: Python code headers = [ ("Cookie",cookiestr) ] request =urllib2.Request(self.url) opener=urllib2.build_opener() opener.addheaders = headers stream = opener.open(request) html = stream.read() --------------------- 这个简单 Python code # coding: UTF-8 import urllib2, httplib, urllib, sys, cookielib if __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; MSIE 6.0; Windows NT 5.1)')] urllib2.install_opener(opener) req=urllib2.Request(url,urllib.urlencode(body)) u=urllib2.urlopen(req) #print u.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'); print u.read().decode('utf-8').encode('gbk') 编写Python程序访问需要cookie的网页 import urllib2,cookielib,urllib,httplib,re cookie=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() #print res cond=True i=0 while cond:     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("\n")     for line in lines:         a=rexp.search(line)         if a:             cond=True             frquene.append(a.groups()[0])              for fr in frquene:     print fr 用Python写点东西,模拟post访问网页 # 加个这个东东看看能不能好 import urllib import http.client headers = {'Accept-Language':'zh-cn','Accept-Charset':'gb18030,utf-8','Accept-Encoding': 'gzip,deflate,bzip2,sdch','User-Agent': 'Mozilla/5.0 (Windows; U; Windows NT 5.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:/My Documents/妗岄潰/url_o.py", line 10, in File "D:\Program Files\Python\lib\http\client.py", line 862, in request     self._send_request(method, url, body, headers) File "D:\Program Files\Python\lib\http\client.py", line 908, in _send_request     self.send(body) File "D:\Program Files\Python\lib\http\client.py", line 689, in send     self.sock.sendall(str) TypeError: sendall() argument 1 must be bytes or buffer, not dict 更新:今天过来写了点新东东,看到这,也更新下吧,前段时候就解决了,因为我用的是Python 3.0,urllib进行了大量的修改以及增强,在3.0的Python中没有urllib2这个库了,能用的都增强到urllib中了,现在的写法很简单了: import urllib.parse import urllib.request url = "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; Windows NT 5.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 >>> import urllib >>> url = 'http://www.baidu.com/' >>> page = urllib.urlopen(url)                     #打开网站,一般需要等待一段时间。时间长短依赖于网站内容 >>> data = page.read() >>> print data 百度一下,你就知道... 例子: #!/usr/bin/env python #coding=utf-8 #file: httpurl.py # import Tkinter import urllib class Window:     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)     def Get(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 # import sys import os import urllib import time ErrLimt = 1000 def WebAnalysis(WebPage = ""):     pass def GenerateName():     currenttime = time.time()     TimeString = time.ctime(currenttime)     TimeString = TimeString.replace(" ", "")     TimeString = TimeString.replace(":", "_") #    print TimeString     FileName = TimeString+'.htm'     return FileName def listDirectory(directory):     "get list of file info objects for files of particular extensions" #    ParaTableList = {}             #Save all parameter table {'ParaTableName:': 0} #    FileList = []                  #Save Open File name     print "Please input the first http link!"     print "Format as:'http://www.hao123.com/'"     WXDownLoadLink = raw_input()            #Record the link name waiting for parase.     print "Please input the second http link!"     print "Format as:'http://www.hao123.com/'"     THDownLoadLink = raw_input()            #Record the link name waiting for parase.     data = ""     ErrorCnt = 0     while True:         try:             page = urllib.urlopen(WXDownLoadLink)             data = page.read()         except:             print ("Web Link Open/Read Error occured at %s" % time.ctime(time.time()))             ErrorCnt += 1             if ErrorCnt >= ErrLimt:                 print ("Error Cnt=%s exceed limt %s " % (ErrorCnt, ErrLimt))                 break             time.sleep(10)             continue         FileName = GenerateName()         FileName = 'WX'+FileName         print FileName         FileName = os.path.join(directory, FileName)         try:             file = open(FileName, 'wb')             file.write(data)             file.close()             page.close()         except:             print ("File Open/write Error occured at %s" % time.ctime(time.time()))             pass         WebAnalysis(data)         data = ""         try:             page = urllib.urlopen(THDownLoadLink)             data = page.read()         except:             print ("Web Link Open/Read Error occured at %s" % time.ctime(time.time()))             ErrorCnt += 1             if ErrorCnt >= ErrLimt:                 print ("Error Cnt=%s exceed limt %s " % (ErrorCnt, ErrLimt))                 break             time.sleep(10)             continue         FileName = GenerateName()         FileName = 'KO'+FileName         print FileName         FileName = os.path.join(directory, FileName)         try:             file = open(FileName, 'wb')             file.write(data)             file.close()             page.close()         except:             print ("File Open/write Error occured at %s" % time.ctime(time.time()))             pass         WebAnalysis(data)         data = "" #        break         time.sleep(60*60)             #Get Web file every one hour.     return 0 if __name__ == "__main__":     result = 0 print "Please input the Directory of the Log!"     print "Windlows Format as:'E:\DeskTop\ADG\Logs Text\Crockett'"     print "Linux Format as:'/home/merlin/DlWeb'"     Filedir = raw_input()     result = listDirectory(Filedir)     if result:         print "There is something error occured!" python抓网页的编码问题 小弟刚接触python,抓第一个网页就过不去编码这个坎`请高手赐教,代码如下: #coding = gb2312 import urllib2 from BeautifulSoup import BeautifulSoup outfile = open("lsxk.txt", "w") for i in range(1,2): #第一页 url= "http://bbs.scu.edu.cn/wForum/disparticle.php? boardName=SCUExpress&ID=1735295349&pos=-1&page=%d" % i doc = 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不能编码网页中的某些字符. 单独使用编码也不能解决: import codecs print open("lsxk.txt").read().decode("utf-8") 可能说的不是很清楚`以上是我遇到的问题们,还请高手帮帮忙,不甚感谢! 最佳答案 BeautifulSoup 版本有问题,使用3.03就可以了 import urllib2 from BeautifulSoup import BeautifulSoup f = urllib.urlopen('http://www.baidu.com') html=f.read() f.close() soup = BeautifulSoup() soup.feed(html) print soup Python抓取网页图片相关代码编写方法 利用Python编程语言进行网页内容的抓取是一个比较常用的编程技术。那么,今天我们将会为大家详细介绍一下有关Python抓取网页图片的操作方法,以方便大家在实际应用中获得一些帮助。 Python抓取网页图片代码示例: 1. ImgDownloader   2. import win32com.client,time,win32inet,win32file,os   3. class ImgDownloader:   4. def __init__(self,url,dir):   5. self.__dir=dir   6. self.__ie=win32com.client.Dispatch('InternetExplorer.Application')   7. self.__ie.Navigate(url)   8. self.__wait__()   9. def __wait__(self):   10. while self.__ie.Busy:   11. time.sleep(0.1)   12. def start(self):   13. self.__wait__()   14. imgs=self.__ie.Document.getElementsByTagName('img')   15. for i in range(imgs.length):   16. try:   17. cachInfo=win32inet.GetUrlCacheEntryInfo(imgs[i].src)   18. if cachInfo:   19. path=cachInfo['LocalFileName']   20. pathpathinfo=path.split('\\')   21. pathinfo.reverse()   22. filename=('[%d]' % i) + pathinfo[0]   23. win32file.CopyFile(path,os.path.join(self.__dir,filename),True)   24. except:   25. pass   26. def close(self):   27. self.__ie.Quit()   28. if __name__=='__main__':   29. d=ImgDownloader('http://image.baidu.com/i?ct=201326592&cl=2& lm=-1&tn=baiduimage&pv=&word=boy&z=0','c:\\temp\\')   30. d.start()   31. d.close()  原理:在Python使用com 接口运行IE浏览器,然后打开网页,获取网页所有图片的URL,最后利用win32api函数GetUrlCacheEntryInfo找出图片相应的本地缓存文件,复制到指定目录。 以上就是我们为大家介绍的Python抓取网页图片的应用方式。 BeautifulSoup Python抓网页小例子 收藏 view plaincopy to clipboardprint? 01.# -*- coding: utf-8 -*- 02.import urllib2 03.from BeautifulSoup import BeautifulSoup, Tag 04.import re 05.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 = '''''<html xmlns="http://www.w3.org/1999/xhtml"> 11.<head> 12.<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 13.<title>keyunq tickets 14. 15. 16. 17. 20. 21.''' 22.fp.write('%s\n' % doc) 23.for i in ss: 24. i.dt['class'] = 'list_piao_time' 25. tmp = i.a['href'] 26. i.a['href'] = 'http://bj.ganji.com'+tmp 27. 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'+tmp 32. 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. print i 38. #i.dd.insert(0, str(phone[0].img)) 39. fp.write('%s\n' % i) 40.doc = ''''' 41.''' 42.fp.write('%s\n' % doc) 43.fp.close() # -*- coding: utf-8 -*- import urllib2 from BeautifulSoup import BeautifulSoup, Tag import re page = 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 = ''' keyunq tickets ''' fp.write('%s\n' % doc) for i in ss: i.dt['class'] = 'list_piao_time' tmp = i.a['href'] i.a['href'] = 'http://bj.ganji.com'+tmp phonepage = 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'+tmp tag1 = Tag(soup, "dd") tag1['class'] = 'list_piao_mj' i.insert(8,tag1) text = str(phone[0].img) tag1.insert(1,text) print i #i.dd.insert(0, str(phone[0].img)) fp.write('%s\n' % i) doc = ''' ''' fp.write('%s\n' % doc) fp.close() BeautifulSoup是用Python写的一个HTML/XML的解析器,它可以很好的处理不规范标记并生成剖析树(parse tree)。 它提供简单又常用的导航(navigating),搜索以及修改剖析树的操作。它可以大大节省你的编程时间。 BeautifulSoup中文文档地址 本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/keyunq/archive/2010/02/02/5282174.aspx Python抓网页内容 用Python语言写搜索引擎蜘蛛的脚本非常简单、轻松。给大家分享两种抓网页内容的方法 一、用urllib2/sgmllib包,将目标网页的所有URL列出。 import urllib2 from sgmllib import SGMLParser class 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) f = urllib2.urlopen("http://www.donews.com/") if f.code == 200:     parser = URLLister()     parser.feed(f.read())     f.close()     for url in parser.urls: print url 二、用python调用IE抓取目标网页(Require win32com, pythoncom)的所有图像的url和大小 import win32com.client, pythoncom import time ie = win32com.client.DispatchEx('InternetExplorer.Application.1') ie.Visible = 1 ie.Navigate("http://news.sina.com.cn") while ie.Busy:     time.sleep(0.05) doc = ie.Document for i in doc.images:     print i.src, i.width, i.height 这种方法可以利用IE本身的Javascript. DHTML的支持,来做自动提交Form,和处理Javascript。 有关样例可以参考 http://win32com.de Python爬虫 1)Python版简单网络爬虫 URLLister类,负责从HTML文本中根据标签提取URL,但也会提取一些垃圾URL,有待改进 from sgmllib import SGMLParser class 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) getURL(url)用来将HTML中的url放入urls列表中 import urllib, urllister def getURL(url): try: usock = urllib.urlopen(url) except: print 'get url excepton' return [] parser = urllister.URLLister() parser.feed(usock.read()) usock.close() parser.close() urls = parser.urls return urls spider(startURL,depth)递归调用getURL(url),startURL为起始URL,depth为递归次数,及遍历的深度 def spider(startURL, depth): i = 0 global num #num为全局变量,用来记录打印的url的数目 if depth <= i: return 0 else: urls = getURL(startURL) if len(urls) > 0: for url in urls: print url, num num = num + 1 spider(url,depth - 1) else: return 0 return 1 调用spider num = 0 spider("http://www.xjtu.edu.cn/",2) 运行结果: 得到962个url,不过其中有一些不符合URL格式的“假货”,比如“nav.php?type=2 944” “http://gs.xjtu.edu.cn/zhaos/upload/files/462498fcd3d35.doc 285”等 而且每次到.doc这里都会很费时间,可见这个“假货”处理速度很慢。 用正则表达式可以判断URL的合法性,待续…… (2)小小的爬虫程序 Python有一个urllib的库,可以很方便的从给定的url抓取网页,以下这段程序实现了抓取一个url并存到指定文件的功能:    爬虫工作的基本原理就是,给定一个初始的url,下载这个url的网页,然后找出网页上所有满足下载要求的链接,然后把这些链接对应的url下载下 来,然后再找下载下来的这些网页的url,我们可以用广度优先搜索实现这个算法,不过,首先得有一个函数找出网页上所有的满足要求的url,下面这个例子 用正则表达式找出url.    最后就是广度优先搜索了,这个实现起来也很简单:    作者用上面的算法,感觉速度还行,1小时可以抓10000多网页,可以满足小型系统的要求。 (3)小爬虫1.0 ----Spider.py-------- #!/usr/local/bin/python from mySpider import * def main(): mySpider = miniHTMLParser() Site = mySpider.site_find() for s in Site: 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_url xmlist = [] #while link != '': while link != root_url : print "\nChecking link ", domain+link raw_html = mySpider.gethtmlfile( domain, link ) mySpider.raw_html = raw_html mySpider.encode = 'utf-8' cleaned_html = mySpider.html_feed() # Get Content clean_theater_name = mySpider.clean_html( name_index, name_keyword ) clean_theater_description = mySpider.clean_html( description_index, description_keyword ) # Save Image try: 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() if next_link[0:1] != '/' : next_link = root_url + next_link link = next_link mySpider.close() print "\ndone\n" xml_input = ('Spider', [('Content', xmlist)] ) mySpider.save_xml(xml_file,xml_input) if __name__ == "__main__": main() ---mySpider.py---- #!/usr/local/bin/python import httplib import sys import re from pyfo import pyfo import urllib2 from BeautifulSoup import BeautifulSoup ,SoupStrainer ,BeautifulStoneSoup from HTMLParser import HTMLParser class miniHTMLParser( HTMLParser ): viewedQueue = [] instQueue = [] search_keyword = '' encode = 'utf-8' raw_html = '' config = 'config.xml' def get_next_link( self ): if self.instQueue == []: return '' else: return self.instQueue.pop(0) def gethtmlfile( self, site, page ): try: httpconn = httplib.HTTPConnection(site) httpconn.request("GET", page) resp = httpconn.getresponse() resppage = resp.read() except: resppage = "" return resppage def handle_starttag( self, tag, attrs ): if tag == 'a': newstr = str(attrs[0][1]) if re.search('http', newstr) == None: if re.search('mailto', newstr) == None: if re.search( self.search_keyword, newstr) != None: if (newstr in self.viewedQueue) == False: print " adding", newstr self.instQueue.append( newstr ) self.viewedQueue.append( newstr ) else: print " ignoring", newstr else: print " ignoring", newstr else: print " ignoring", newstr def clean_html(self, index, keyword): soup = self.get_soup() html_source = str( soup.findAll( attrs={ index : re.compile(keyword+"$")}) ) clean_html_source = re.sub('<(?!(?:a\s|/a|!))[^>]*>','',html_source) clean_html_source = clean_html_source.replace('\n', '') clean_html_source = clean_html_source.replace('[', '') clean_html_source = clean_html_source.replace(']', '') clean_html_source = clean_html_source.strip() return clean_html_source def clean_description_list(self, index, keyword): clean_description_list = [] clean_html_source = self.clean_html(index, keyword) t = clean_html_source.split(':') for g in t: g = g.strip() s = g.split(' ') for tag in s: if tag != '': tag = tag.strip() tag = tag[0:10] if tag != ' www.example1.com.cn /movie/ theater.asp image/ -2 Crawling Page/piao.html bgcolor #2B2B2B bgcolor #4B4B4B width 169 Crawing Content/piao.xml theater.asp www.example.com /theater/intro/BeiJing/ CHANGHONG/ image/ -5 Crawling Page/mvgod.html class main class namezi style float:right;margin:4px Crawing Content/mvgod.xml /theater/intro/BeiJing/ (4)用python编写网络爬虫 刚刚开了一个《计算机网络》的课,觉得很有用。正好师兄让我练习编写一个能下载网站网页的程序,正好能用上课上的知识了。为了想作一个效率不差的,而下载网页的性能瓶颈是在网络上,所有决定用Python编写代码。刚学python没几天,学习一种语言的最好方法就是写code.下面的是我用的多线程实现的网络爬虫,并用py2exe生成了一个exe,自身觉得py2exe不太好,又不会更好的,只能...... 这是我这些天的成果。希望有人能提出好的建议,先谢谢了!一共两个文件,一个是toolbox_insight.py,是一个工具文件另一个是test.py,是一个用到toolbox_insight.py中工具的测试文件 #FileName: toolbox_insight.py from sgmllib import SGMLParser import threading import time import urllib2 import StringIO import gzip import string import os #rewrite SGMLParser for start_a class Basegeturls(SGMLParser): #这个Basegeturls类作用是分析下载的网页,把网页中的所有链接放在self.url中。 def reset(self): self.url = [] SGMLParser.reset(self) def start_a(self, attrs): href = [v for k, v in attrs if k == 'href'] if href: self.url.extend(href) #for quickly finding class Newlist(list):#这个类其实是一个添加了find方法的LIST。当num变量在LIST中,返回True,当不在LIST中,返回False并把num按二分法插入LIST中 def find(self, num): l = len(self) first = 0 end = l - 1 mid = 0 if l == 0: self.insert(0,num) return False while first < end: mid = (first + end)/2 if num > self[mid]: first = mid + 1 elif num < self[mid]: end = mid - 1 else: break if first == end: if self[first] > num: self.insert(first, num) return False elif self[first] < num: self.insert(first + 1, num) return False else: return True elif first > end: self.insert(first, num) return False else: return True #下面的reptile顾名思义是一个爬虫 class reptile(threading.Thread): #Name: 是爬虫是名字,queue是任务队列,所有的爬虫共用同一个任务队列 #从中取出一个任务项进行运行,每个任务项是一个要下载网页的URL #result: 也是一个队列,将下载的网页中包含的URL放入该队列中 #inittime: 在本程序中没有用,只是一个为了以后扩展用的 #downloadway:是下载的网页存放的路径 #configfile: 是配置文件,存放网页的URL和下载下后的路径 #maxnum: 每个爬虫有个最大下载量,当下载了这么多网页后,爬虫dead def __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 = queue self.result = result self.Flcok = Flcok self.inittime = inittime self.mainway = downloadway self.configfile = configfile self.num = 0 #已下载的网页个数 self.maxnum = maxnum os.makedirs(downloadway + self.getName()) #系统调用:在存放网页的文件夹中创建一个以该爬虫name为名字的文件夹 self.way = downloadway + self.getName() + '\\' def run(self): opener = urllib2.build_opener() #创建一个开启器 while True: url = self.queue.get() #从队列中取一个URL if url == None: #当取得一个None后表示爬虫结束工作,用于外部方便控制爬虫的生命期 break parser = Basegeturls() #创建一个网页分析器 request = urllib2.Request(url) #网页请求 request.add_header('Accept-encoding', 'gzip')#下载的方式是gzip压缩后的网页,gzip是大多数服务器支持的一种格式 try: #这样可以减轻网络压力 page = opener.open(request)#发送请求报文 if page.code == 200: #当请求成功 predata = page.read() #下载gzip格式的网页 pdata = StringIO.StringIO(predata)#下面6行是实现解压缩 gzipper = gzip.GzipFile(fileobj = pdata) try: data = gzipper.read() except(IOError): print 'unused gzip' data = predata#当有的服务器不支持gzip格式,那么下载的就是网页本身 try: parser.feed(data)#分析网页 except: print 'I am here'#有的网页分析不了,如整个网页就是一个图片 for item in parser.url: self.result.put(item)#分析后的URL放入队列中 way = self.way + str(self.num) + '.html'#下面的是网页的保存,不多说了 self.num += 1 file = open(way, 'w') file.write(data) file.close() self.Flcok.acquire() confile = open(self.configfile, 'a') confile.write( way + ' ' + url + '\n') confile.close() self.Flcok.release() page.close() if self.num >= self.maxnum:#达到最大量后退出 break except: print 'end error' #和爬虫一样是个线程类,作用是将爬虫中的result中存入的URL加以处理。只要同一个服务器的网页 class proinsight(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的去处 def run(self): length = len(self.homepage) while True: item = self.queue.get() if item == None: break if item[0:4] == '\r\n': item = item[4:] if item[-1] == '/': item = item[:-1] if len(item) >= len('http://') and item[0:7] == 'http://': if len(item) >= length and item[0:length] == self.homepage: if self.list.find(item) == False: self.inqueue.put(item) elif item[0:5] == '/java' or item[0:4] == 'java': pass else: if item[0] != '/': item = '/' + item item = self.homepage + item if self.list.find(item) == False: self.inqueue.put(item) 下面的是一个主函数过程 我下载的网站是http://bbs.hit.edu.cn 开始网页是http://bbs.hit.edu.cn/mainpage.php #FileName:test from toolbox_insight import * from Queue import Queue import threading import sys num = int(raw_input('Enter the number of thread:')) pnum = int(raw_input('Enter the number of download pages:')) mainpage = str(raw_input('The mainpage:')) startpage = str(raw_input('Start page:')) queue = Queue() key = Queue() inqueue = Queue() list = Newlist() thlist = [] Flock = threading.RLock() for i in range(num): th = reptile('th' + str(i), queue, key, Flock) thlist.append(th) pro = proinsight(key, list, mainpage, inqueue) pro.start() for i in thlist: i.start() queue.put(startpage) for i in range(pnum): queue.put(inqueue.get()) for i in range(num): queue.put(None) 个人觉得用wxpython来实现用户界面和用数据库知识查找URL是更好的扩展方向 用python编写分布式爬虫 1、 网络连接需要持续连接(persistent connection),DNS解析的瓶颈(先查本地DNS缓存) 实 现方法:基于python httplib(对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.txt 5、 单个机器spider的作用: a) 同2多线程3文件树的遍历 b) 将获取的外部url发回中央控制器,并从中央控制器取回新的外部url。 6、 中央控制器的作用: a) 观察各机器的状态包括:cpu、内存、线程、站点、网络流量 b) 观察对外整体网络流量和连接状况,可以根据网络状况来调节timeout。 c) 接受各个机器发送过来的外部url并对每个url的重复数字计数。然后分配到各个机器。(分配时要用爬行策略控制器对外部url进行排序来分配,Igloo利用Page Rank,我们可以使用最简单的重复越多重要系数就越高来进行排序) d) 分布式URL分配算法:Igloo1.2的二级哈希映射算法(集中式分配算法那个中央控制器容易成为系统瓶颈)复习哈希算法,还有就是对url是否访问过 的判断(Igloo使用的是URL Trie滞后合并策略)。可以使用Berkeley DB作为URL Trie的替代品。两种实现方式的比较: i. 现在的想法:(面向站点,信息颗粒大)外部链接只是保存主机名比如:www.163.com, 站内访问用解析好的ip地址维持连接,用相对链接来得到各个页面,这样就要维护一个外部链接列表,几个站点的链接列表。优点:节省内存,对某个站点的信息 获取全面,对站点的出现频率统计,排序,重要站点先取。 缺点:对链接的获取的全面性得不到保证,而且不能获取更多的重要页面,每个站点的重要页面也不会很多。 ii. 老方案:(面向页面,信息颗粒小)所有连接一视同仁。缺点:浪费资源,对单一站点的获取不一定全面。优点:可以得到全面的链接图,可以使用Page Rank对列表进行排序,页面更重要就在最前面。 7、 解析html(超级链接的提取)搞定(用python的sgmllib)缺点:速度太慢(可能会造成瓶颈,要好好包装好,以后有机会换掉它) 5多线程实例 view plaincopy to clipboardprint? # -*- coding:utf-8 -*- import urllib, httplib import thread import time from Queue import Queue, Empty, Full HEADERS = {"Content-type": "application/x-www-form-urlencoded", 'Accept-Language':'zh-cn', 'User-Agent': 'Mozilla/4.0 (compatible; MSIE 6.0;Windows NT 5.0)', "Accept": "text/plain"} UNEXPECTED_ERROR = -1 POST = 'POST' GET = 'GET' def base_log(msg): print msg def base_fail_op(task, status, log): log('fail op. task = %s, status = %d'%(str(task), status)) def get_remote_data(tasks, results, fail_op = base_fail_op, log = base_log): while True: task = tasks.get() try: tid = task['id'] hpt = task['conn_args'] # hpt <= host:port, timeout except KeyError, e: log(str(e)) continue log('thread_%s doing task %d'%(thread.get_ident(), tid)) #log('hpt = ' + str(hpt)) conn = httplib.HTTPConnection(**hpt) try: params = task['params'] except KeyError, e: params = {} params = urllib.urlencode(params) #log('params = ' + params) try: method = task['method'] except KeyError: method = 'GET' #log('method = ' + method) try: url = task['url'] except KeyError: url = '/' #log('url = ' + url) headers = HEADERS try: tmp = task['headers'] except KeyError, e: tmp = {} headers.update(tmp) #log('headers = ' + str(headers)) headers['Content-Length'] = len(params) try: if method == POST: conn.request(method, url, params, headers) else: conn.request(method, url + params) response = conn.getresponse() except Exception, e: log('request failed. method = %s, url = %s, params = %s headers = %s'%( method, url, params, headers)) log(str(e)) fail_op(task, UNEXPECTED_ERROR, log) continue if response.status != httplib.OK: fail_op(task, response.status, log) continue data = response.read() results.put((tid, data), True) class HttpPool(object): def __init__(self, threads_count, fail_op, log): self._tasks = Queue() self._results = Queue() for i in xrange(threads_count): thread.start_new_thread(get_remote_data, (self._tasks, self._results, fail_op, log)) def add_task(self, tid, host, url, params, headers = {}, method = 'GET', timeout = None): task = { 'id' : tid, 'conn_args' : {'host' : host} if timeout is None else {'host' : host, 'timeout' : timeout}, 'headers' : headers, 'url' : url, 'params' : params, 'method' : method, } try: self._tasks.put_nowait(task) except Full: return False return True def get_results(self): results = [] while True: try: res = self._results.get_nowait() except Empty: break results.append(res) return results def test_google(task_count, threads_count): hp = HttpPool(threads_count, base_fail_op, base_log) for i in xrange(task_count): if hp.add_task(i, 'www.google.cn', '/search?', {'q' : 'lai'}, # method = 'POST' ): print 'add task successed.' while True: results = hp.get_results() if not results: time.sleep(1.0 * random.random()) for i in results: print i[0], len(i[1]) # print unicode(i[1], 'gb18030') if __name__ == '__main__': import sys, random task_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.aspx Python如何使用urllib2获取网络资源 · urllib2是Python的一个获取URLs(Uniform Resource Locators)的组件。他以urlopen函数的形式提供了一个非常简单的接口, 这是具有利用不同协议获取URLs的能力,他同样提供了一个比较复杂的接口来处理一般情况,例如:基础验证,cookies,代理和其他。 它们通过handlers和openers的对象提供。 urllib2支持获取不同格式的URLs(在URL的":"前定义的字串,例如:"ftp"是"ftp:python.ort/"的前缀),它们利用它们相关网络协议(例如FTP,HTTP) 进行获取。这篇教程关注最广泛的应用--HTTP。 对于简单的应用,urlopen是非常容易使用的。但当你在打开HTTP的URLs时遇到错误或异常,你将需要一些超文本传输协议(HTTP)的理解。 最权威的HTTP文档当然是RFC 2616(http://rfc.net/rfc2616.html)。这是一个技术文档,所以并不易于阅读。这篇HOWTO教程的目的是展现如何使用urllib2, 并提供足够的HTTP细节来帮助你理解。他并不是urllib2的文档说明,而是起一个辅助作用。 获取 URLs 最简单的使用urllib2将如下所示 Python code import urllib2 response = urllib2.urlopen(http://python.org/) html = response.read() urllib2的很多应用就是那么简单(记住,除了"http:",URL同样可以使用"ftp:","file:"等等来替代)。但这篇文章是教授HTTP的更复杂的应用。 HTTP是基于请求和应答机制的--客户端提出请求,服务端提供应答。urllib2用一个Request对象来映射你提出的HTTP请求,在它最简单的使用形式中你将用你要请求的 地址创建一个Request对象,通过调用urlopen并传入Request对象,将返回一个相关请求response对象,这个应答对象如同一个文件对象,所以你可以在Response中调用.read()。 Python code import urllib2 req = urllib2.Request(http://www.voidspace.org.uk) response = urllib2.urlopen(req) the_page = response.read() 记得urllib2使用相同的接口处理所有的URL头。例如你可以像下面那样创建一个ftp请求。 Python code req = 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。 Python code import urllib import urllib2 url = http://www.someserver.com/cgi-bin/register.cgi values = {name : Michael Foord, 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.13 HTML Specification, Form Submission的详细说明)。 如ugoni没有传送data参数,urllib2使用GET方式的请求。GET和POST请求的不同之处是POST请求通常有"副作用",它们会由于某种途径改变系统状态(例如提交成堆垃圾到你的门口)。 尽管HTTP标准说的很清楚POSTs通常会产生副作用,GET请求不会产生副作用,但没有什么可以阻止GET请求产生副作用,同样POST请求也可能不产生副作用。Data同样可以通过在Get请求 的URL本身上面编码来传送。 可看如下例子 Python code >>> import urllib2 >>> import urllib >>> data = {} >>> data[name] = Somebody Here >>> data[location] = Northampton >>> data[language] = Python >>> url_values = urllib.urlencode(data) >>> print url_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头,当你创建了一个请求对象,你可以给他一个包含头数据的字典。下面的例子发送跟上面一样的内容,但把自身 模拟成Internet Explorer。 Python code import urllib import urllib2 url = http://www.someserver.com/cgi-bin/register.cgi user_agent = Mozilla/4.0 (compatible; MSIE 5.5; Windows NT) values = {name : Michael Foord, 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应答对象同样有两个很有用的方法。看下面的节info and geturl,我们将看到当发生错误时会发生什么。 Handle Exceptions处理异常 当urlopen不能够处理一个response时,产生urlError(不过通常的Python APIs异常如ValueError,TypeError等也会同时产生)。 HTTPError是urlError的子类,通常在特定HTTP URLs中产生。 URLError 通常,URLError在没有网络连接(没有路由到特定服务器),或者服务器不存在的情况下产生。这种情况下,异常同样会带有"reason"属性,它是一个tuple,包含了一个错误号和一个错误信息。 例如 Python code >>> req = urllib2.Request(http://www.pretend_server.org) >>> try: urllib2.urlopen(req) >>> except URLError, e: >>> print e.reason >>> (4, getaddrinfo failed) HTTPError 服务器上每一个HTTP 应答对象response包含一个数字"状态码"。有时状态码指出服务器无法完成请求。默认的处理器会为你处理一部分这种应答(例如:假如response是一个"重定向",需要客户端从别的地址获取文档 ,urllib2将为你处理)。其他不能处理的,urlopen会产生一个HTTPError。典型的错误包含"404"(页面无法找到),"403"(请求禁止),和"401"(带验证请求)。 请看RFC 2616 第十节有所有的HTTP错误码 HTTPError实例产生后会有一个整型code属性,是服务器发送的相关错误号。 Error Codes错误码 因为默认的处理器处理了重定向(300以外号码),并且100-299范围的号码指示成功,所以你只能看到400-599的错误号码。 BaseHTTPServer.BaseHTTPRequestHandler.response是一个很有用的应答号码字典,显示了RFC 2616使用的所有的应答号。这里为了方便重新展示该字典。(译者略) 当一个错误号产生后,服务器返回一个HTTP错误号,和一个错误页面。你可以使用HTTPError实例作为页面返回的应答对象response。这表示和错误属性一样,它同样包含了read,geturl,和info方法。 Python code >>> req = urllib2.Request(http://www.python.org/fish.html) >>> try: >>> urllib2.urlopen(req) >>> except URLError, e: >>> print e.code >>> print e.read() >>> 404 Error 404: File Not Found ...... etc... Wrapping it Up包装 所以如果你想为HTTPError或URLError做准备,将有两个基本的办法。我则比较喜欢第二种。 第一个: Python code from urllib2 import Request, urlopen, URLError, HTTPError req = Request(someurl) try: response = urlopen(req) except HTTPError, e: print The server couldn\t fulfill the request. print Error code: , e.code except URLError, e: print We failed to reach a server. print Reason: , e.reason else: # everything is fine 注意:except HTTPError 必须在第一个,否则except URLError将同样接受到HTTPError。 第二个: Python code from urllib2 import Request, urlopen, URLError req = Request(someurl) try: response = urlopen(req) except URLError, e: if hasattr(e, reason): print We failed to reach a server. print Reason: , e.reason elif hasattr(e, code): print The server couldn\t fulfill the request. print Error code: , e.code else: # everything is fine info and geturl urlopen返回的应答对象response(或者HTTPError实例)有两个很有用的方法info()和geturl() geturl -- 这个返回获取的真实的URL,这个很有用,因为urlopen(或者opener对象使用的)或许 会有重定向。获取的URL或许跟请求URL不同。 info -- 这个返回对象的字典对象,该字典描述了获取的页面情况。通常是服务器发送的特定头headers。目前是httplib.HTTPMessage 实例。 经典的headers包含"Content-length","Content-type",和其他。查看Quick Reference to HTTP Headers(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重定向或者HTTP cookies。 如果你希望用特定处理器获取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,除了为了方便。

下载文档到电脑,查找使用更方便

文档的实际排版效果,会与网站的显示效果略有不同!!

需要 5 金币 [ 分享文档获得金币 ] 1 人已下载

下载文档