用Python快速编写网站遍历程序

来源:互联网 发布:网络剧 受众群体 编辑:程序博客网 时间:2024/05/21 08:38

 

 

前言


Python是一个相当有意思的语言,当我一看到她就喜欢上了她,她实在是太棒了!~
这是我学习python写的第一个程序,就算是练练手吧。
我现在把编写的过程记录下来,以后忘记了可以在回来看看,呵呵,同时也希望给各位跟我一样的初学者一个参考,有错误地方希望大大们帮我指出来一下,不要笑我啊!

 


 

 

1、登陆
在这里遇到的第一个问题就是某些网站是需要登陆的
于是就产生了LoginWebsite这个函数,他使用urllib2的urlopen方式登录网站,并获取Cookie。(当然,这里也可以改为获取Session,具体情况具体讨论吧)。

def LoginWebsite(longinURL,params):
    """
    Login websie and get it's Cookie      /n/r
    longinURL:登陆网址        
    如:
http://www.target.com/upload/logging.php?action=login
    params:     传入的参数
    如 username=DeamonTX&password=123456&loginsubmit=%B4%A3%A5%E6
    """
    cookiejar=cookielib.CookieJar()
    cookie=""   
    opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookiejar))
    urllib2.install_opener(opener)
    try:   
        urllib2.urlopen(longinURL, params )
    except:
        return cookie
    for c in cookiejar:
        cookie+=c.name+'='+c.value+';'
return cookie[0:-2]   

来看看这个函数的实现吧:
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookiejar))
可以将一个CookieJar安装到opener上,于是,在使用urlopen后,网页所产生的cookie就会传入cookiejar。
Cookiejar是由元组组成的构成的,这里是当时我所获得的一个cookiejar:

 

 [Cookie(version=0, name='cdb_auth', value='bm13KO%2BSYOK3HqtzAqS01vRxJWvxhVMgivNX9I73%2B3WrIro%2BDEep6K1%2B6RL0%2BDY', port=None, port_specified=False, domain='www.3-wolves.com', domain_specified=False, domain_initial_dot=False, path='/', path_specified=True, secure=False, expires=None, discard=True, comment=None, comment_url=None, rest={}, rfc2109=False),
Cookie(version=0, name='cdb_cookietime', value='0', port=None, port_specified=False, domain='www.3-wolves.com', domain_specified=False, domain_initial_dot=False, path='/', path_specified=True, secure=False, expires=1238327970, discard=False, comment=None, comment_url=None, rest={}, rfc2109=False),
Cookie(version=0, name='cdb_sid', value='lF8KS2', port=None, port_specified=False, domain='www.3-wolves.com', domain_specified=False, domain_initial_dot=False, path='/', path_specified=True, secure=False, expires=1207396770, discard=False, comment=None, comment_url=None, rest={}, rfc2109=False)]

可以看到元组中有多个Cookie对象,在这里我们只需要获得其name和value就够了

 

2、获取网页内容
没有难度,直接贴代码吧

def GetHtmlContent(url,ref="",cookie="",decode="",encode=""):
    request = urllib2.Request(url)
    request.add_header("Reference", ref)
    request.add_header("Cookie", cookie)
    opener = urllib2.build_opener()
    try:
        content = opener.open(request).read()
        if (decode!=""):
            content = content.decode(decode, 'ignore')
        if (encode!=""):
            content = content.encode(encode)
    except:
        content=""   
    return content

 


 


3、遍历网页中的标签,并获得其属性
在这里其实可以通过htmllib.HTMLParser类来实现,但是我发现在遇到big5等方式编码的网页时容易出错,所以这里改用正则表达式来实现,这是个很有意思的东西。
看一下这段代码:
    r='<’+ tagname +’(?:(?://s*.*?//s)|(?://s+))’+ attrname +’=(?P<val>/S*?)(?:(?://s.*>)|(?:>))'
    rawvals =re.compile(r).findall(content)
    for p in rawvals:
        #去除首尾的引号和空格
        attrval=p.strip(' /"')      
        vals.append(attrval)
这样将获得以”<tagname”开头,”>”中attrname=的值
正则表达式看不懂得话就请查阅相关书籍,这不是一两句话能说清的东西。(可以参考我blog转载的
Python正则表达式操作指南
但是在使用过程中我发现,如果一行中有两个或两个以上要查找的tag的话,他只能识别出一个,原因不明,郁闷…
所以还需要加上一句content=string.replace(content,’<’+tagname,’/r/n<’++tagname)
下面给出完整源代码:


def EnumHTMLPics(startURL,HTML,tagname,attrname):
    vals =[]
    content=HTML
    if (len(content)<=0):
        return vals
    content=string.replace(content,’<’+tagname,’/r/n<’++tagname)
    rawvals =[]
    r='<’+ tagname +’(?:(?://s*.*?//s)|(?://s+))’+ attrname +’=(?P<val>/S*?)(?:(?://s.*>)|(?:>))'
    rawvals =re.compile(r).findall(content)
    for p in rawvals:
        #去除首尾的引号和空格
        attrval=p.strip(' /"')      
        vals.append(attrval)
return vals

 

4、路径转换
大家都知道,网页中的路径分为相对路径和绝对路径,我们要想遍历网站的话,就必须将相对路径转换为绝对路径。实现方法很简单,我就直接给出代码吧。

def TransAbsURL(refURL,url):
    """取绝对路径"""
    website=""
    webdir=""
    r='http://(?P<website>.*?)[/$]'
    website=re.compile(r,re.IGNORECASE).findall(refURL)[0]
    #取当前URL目录
    if(refURL[-1]=='/'):
        webdir=refURL
    else:
        index=string.rfind(refURL,'/')
        if (index<7):
            webdir='http://'+website+'/'
        else:
            webdir=refURL[0:index+1]
    #绝对地址,直接返回
    if (string.find(url.lower(),"http://")>=0):
        return url
    #相对地址
    else:
        if (url[0]=='/'):
            return 'http://'+website+url
        else:
            return webdir+url

 

5遍历超链接

其实这里的方法和遍历网页中的标签很相似,就先贴出代码吧。


def EnumHTMLLinks(startURL,HTML):
    links=[]
    content=HTML
    if (len(content)<=0):
        return links
    content=string.replace(content,"<a","/r/n<a")
    rawlinks=[]
    r='<a(?:(?://s*.*?//s)|(?://s+))href=(?P<url>/S*?)(?:(?://s.*>)|(?:>))(?P<name>.*?)</a>'
    rawlinks=re.compile(r).findall(content)
    for l in rawlinks:
        #去除首尾的引号和空格,然后转为绝对路径
        linkurl=TransAbsURL(startURL,l[0].strip(' /"'))     
  #将html编码转为text 
        h2t=html2txt()
        h2t.feed(l[1])
        h2t.close()
        linkname=h2t.text
        links.append([linkurl,linkname])
    return links

可以看到,这里的正则表达式和前面的稍微有些不一样,通过这个表达式,我们将不仅可以获得<a>中href的值,同时还可以获取<a></a>中的数据。
前面我们讲到的绝对路径的转换在这里我们也用到了:
linkurl=TransAbsURL(startURL,l[0].strip(' /"'))

 

6、html向text的转换
如果仔细看了前面的代码的话可以看到这么几句:
        h2t=html2txt()
        h2t.feed(l[1])
        h2t.close()
        linkname=h2t.text
我们知道,在<a></a>之间可能不仅仅只是普通的文字,可能还有其他标签以及html的转义符,如此我们就需要将其转换为普通的文字。以上代码中的html2txt类就是用于将html转换为txt的。具体实现看下面吧(代码是我抄的,通过sgmllib. SGMLParser类来实现,很简单,还是只贴代码,不解释了吧)。


class html2txt(SGMLParser):
    def reset(self):
        self.text = ''
        self.inbody = True
        SGMLParser.reset(self)
    def handle_data(self,text):
        if self.inbody:
            self.text += text
    def start_head(self,text):
        self.inbody = False
    def end_head(self):
        self.inbody = True

   


好了,基本的函数就已经写完了,今天就也就暂时写到这里吧,明天如果有时间的话再继续吧!

 

原创粉丝点击