根据网页源码提取url

自学3天后,写出了这个,代码很笨拙,自己也觉得,我觉得遇到的最大的困难就是缩进和方法名不熟。

看来还是要多加练习啊


原题是这样的:

 

 

 

测试时间为一周,接受测试人员领取试题,通过看书和搜索学习之后作答,并以电子邮件形式回复。期间有任何关于Python的问题也可以发送电子邮件询问,作者会在不影响测试效果的情况下尽快回答。

 

参考书目可以只看《简明Python教程》,沈洁元译。使用的Python版本为2.5.4,不要使用其他版本。

 

测试题目

----------

 

分析科学松鼠会的网站首页。

 

使用自己方便的方法下载科学松鼠会网站的首页,并保存为一个文件。然后通过程序分析该问题提取其中的所有URL,并将这些URL以每行一个的方式输出到一个文本文件中。

 

测试内容主要面向字符串分析和简单文件操作。

 

细节提示

----------

 

#. 输出的URL列表必须是完整的URL,包括松鼠会的域名。例如 ``http://songshuhui.net/wp-content/themes/isongshu/style.css`` 。

#. 可以利用任何浏览器打开松鼠会首页,然后在页面单击邮件,查看源代码并保存。

#. 注意相对URL的分析,"/"开头的是根URL,前面加域名等前缀即可,否则则是相对URL,需要提取相关的当前路径。

#. 注意打开源文件时的编码字符集。

#. 去掉重复的URL。

#. 可以忽略掉JavaScript代码中的拼接URL。

#. 最多产生URL的标签是"<a>"和"<img>",其他的标签也需要分析,并影响评分。

#. URL不会被切分多多行,一般来说URL是在双引号中。

 

主要困难出在不知道如何判断相对url,采用方法是根据标签提取属性的内容。

 

 

--------------------------------------------

#!C:\Python25\python.exe

#-*- encoding: gb2312 -*-

#使用版本为2.5.4

#下载首页命名为songshuhui[1].txt

#在做这个题的时候,想到了两个办法,一个是以“为分隔符分割整片源代码,后来觉得这样不准确,于是又改为是根据标签来解析标签下href的值,然后筛选后再用别的方法解析用标签没有解析到的。

import HTMLParser

import re

class MyParser(HTMLParser.HTMLParser):   

    def __init__(self):   

        HTMLParser.HTMLParser.__init__(self)

        self.listOld = []

    #这里是用handle_comment来解析源码中<!--注释中的url

    def handle_comment(self, data):

        if data.find(" http://")>0:

            url = re.search("( http://.*)", data).group(1)

            self.listOld.append(url)

    #这里主要就是对标签下的属性进行url提取

    def handle_starttag(self, tag, attrs):

        # 这里重新定义了处理开始标签的函数

        if tag == 'a':   

            # 判断标签<a>的属性   

            for name,value in attrs:

                #如果<a>标签下的<href>的值内不包含<,这么做的原因是因为测试中发现有一个标签<a>的herf是一个<img>,相当于<a>里面嵌套了标签<img>,所以多加一层判断

                if value.find("<")<0:

                    #属性名为href并且该值不为空

                    if name == 'href' and value!= '':

                        #如果这个值里包括http就说明是绝对路径

                        if value.find('http')>-1:

                            #绝对路径就直接保存至listOld里面

                            self.listOld.append(value)

                        else:

                            #相对路径的话就在前面加上http://songshuhui.net

                            self.listOld.append('http://songshuhui.net/' + value)

                #提取harf中img标签的src的值

                else:

                    #从href里面提取出img的src。根据=分割后的第一个值,去掉最后一个字符">"

                    self.listOld.append(value.split("=")[1][0:len(value.split("=")[1])-1])

        elif tag == 'link':

            # 判断标签<link>的属性

            for name,value in attrs:

                if name =='href' and value!= '':

                    #如果是绝对路径

                    if value.find('http')>-1:

                        self.listOld.append(value)

                    else:

                    #如果是相对路径

                        self.listOld.append('http://songshuhui.net/'+value)

        elif tag == 'img':

            # 判断标签<img>的属性

            for name,value in attrs:

                if name == 'src' and value!= '':

                    #如果是绝对路径

                    if value.find('http')>-1:

                        self.listOld.append(value)

                    #如果是相对路径

                    else:

                        self.listOld.append('http://songshuhui.net/'+value)

        elif tag == 'form':

            # 判断标签<form>的属性

            for name,value in attrs:

                #提取form的action属性值

                if name == 'action' and value!='':

                    self.listOld.append(value)

        elif tag == 'div':

            # 判断标签<form>的属性

            for name,value in attrs:

                #提取div的onclick属性值,以'为分隔,的第一个值,并且包含http

                if name == 'onclick' and value != '' and value.find('http')>-1:

                    #print "测试onclick的值:"+value.split('\'')[1]

                    #结果加入到listOld中

                    self.listOld.append(value.split('\'')[1])

if __name__ == '__main__':

    #获取源代码

    fileA=open('songshuhui[1].txt')

    a=fileA.read()

    my = MyParser()   

    # 传入要分析的数据,也就是科学松鼠会首页 

    my.feed(a)

    d={}

    #这里是去重

    for urls in my.listOld:

        if not d.has_key(urls):

            d[urls]=""

    nlst=[]

    for key in d.keys():

        nlst.append(key)

    #创建SSH.txt,把最终去重后的结果逐行写入

    fileB=open('SSHurl.txt','w')

    for urlstr in nlst:

        fileB.write(urlstr + '\n')

    print 'OK!'

    #清理工作

    fileB.close()

    fileA.close()

 

 

#!C:\Python25\python.exe
#-*- encoding: gb2312 -*-
#使用版本为2.5.4
#下载首页命名为songshuhui[1].txt
#在做这个题的时候,想到了两个办法,一个是以“为分隔符分割整片源代码,后来觉得这样不准确,于是又改为是根据标签来解析标签下href的值,然后筛选后再用别的方法解析用标签没有解析到的。
import HTMLParser
import re
class MyParser(HTMLParser.HTMLParser):   
    def __init__(self):   
        HTMLParser.HTMLParser.__init__(self)
        self.listOld = []
    #这里是用handle_comment来解析源码中<!--注释中的url
    def handle_comment(self, data):
        if data.find(" http://")>0:
            url = re.search("( http://.*)", data).group(1)
            self.listOld.append(url)
    #这里主要就是对标签下的属性进行url提取
    def handle_starttag(self, tag, attrs):
        # 这里重新定义了处理开始标签的函数
        if tag == 'a':   
            # 判断标签<a>的属性   
            for name,value in attrs:
                #如果<a>标签下的<href>的值内不包含<,这么做的原因是因为测试中发现有一个标签<a>的herf是一个<img>,相当于<a>里面嵌套了标签<img>,所以多加一层判断
                if value.find("<")<0:
                    #属性名为href并且该值不为空
                    if name == 'href' and value!= '':
                        #如果这个值里包括http就说明是绝对路径
                        if value.find('http')>-1:
                            #绝对路径就直接保存至listOld里面
                            self.listOld.append(value)
                        else:
                            #相对路径的话就在前面加上http://songshuhui.net
                            self.listOld.append('http://songshuhui.net/' + value)
                #提取harf中img标签的src的值
                else:
                    #从href里面提取出img的src。根据=分割后的第一个值,去掉最后一个字符">"
                    self.listOld.append(value.split("=")[1][0:len(value.split("=")[1])-1])
        elif tag == 'link':
            # 判断标签<link>的属性
            for name,value in attrs:
                if name =='href' and value!= '':
                    #如果是绝对路径
                    if value.find('http')>-1:
                        self.listOld.append(value)
                    else:
                    #如果是相对路径
                        self.listOld.append('http://songshuhui.net/'+value)
        elif tag == 'img':
            # 判断标签<img>的属性
            for name,value in attrs:
                if name == 'src' and value!= '':
                    #如果是绝对路径
                    if value.find('http')>-1:
                        self.listOld.append(value)
                    #如果是相对路径
                    else:
                        self.listOld.append('http://songshuhui.net/'+value)
        elif tag == 'form':
            # 判断标签<form>的属性
            for name,value in attrs:
                #提取form的action属性值
                if name == 'action' and value!='':
                    self.listOld.append(value)
        elif tag == 'div':
            # 判断标签<form>的属性
            for name,value in attrs:
                #提取div的onclick属性值,以'为分隔,的第一个值,并且包含http
                if name == 'onclick' and value != '' and value.find('http')>-1:
                    #print "测试onclick的值:"+value.split('\'')[1]
                    #结果加入到listOld中
                    self.listOld.append(value.split('\'')[1])
if __name__ == '__main__':
    #获取源代码
    fileA=open('songshuhui[1].txt')
    a=fileA.read()
    my = MyParser()   
    # 传入要分析的数据,也就是科学松鼠会首页 
    my.feed(a)
    d={}
    #这里是去重
    for urls in my.listOld:
        if not d.has_key(urls):
            d[urls]=""
    nlst=[]
    for key in d.keys():
        nlst.append(key)
    #创建SSH.txt,把最终去重后的结果逐行写入
    fileB=open('SSHurl.txt','w')
    for urlstr in nlst:
        fileB.write(urlstr + '\n')
    print 'OK!'
    #清理工作
    fileB.close()
    fileA.close()

#!C:\Python25\python.exe#-*- encoding: gb2312 -*-#使用版本为2.5.4#下载首页命名为songshuhui[1].txt#在做这个题的时候,想到了两个办法,一个是以“为分隔符分割整片源代码,后来觉得这样不准确,于是又改为是根据标签来解析标签下href的值,然后筛选后再用别的方法解析用标签没有解析到的。import HTMLParserimport reclass MyParser(HTMLParser.HTMLParser):       def __init__(self):           HTMLParser.HTMLParser.__init__(self)        self.listOld = []    #这里是用handle_comment来解析源码中<!--注释中的url    def handle_comment(self, data):        if data.find(" http://")>0:            url = re.search("( http://.*)", data).group(1)            self.listOld.append(url)    #这里主要就是对标签下的属性进行url提取    def handle_starttag(self, tag, attrs):        # 这里重新定义了处理开始标签的函数        if tag == 'a':               # 判断标签<a>的属性               for name,value in attrs:                #如果<a>标签下的<href>的值内不包含<,这么做的原因是因为测试中发现有一个标签<a>的herf是一个<img>,相当于<a>里面嵌套了标签<img>,所以多加一层判断                if value.find("<")<0:                    #属性名为href并且该值不为空                    if name == 'href' and value!= '':                        #如果这个值里包括http就说明是绝对路径                        if value.find('http')>-1:                            #绝对路径就直接保存至listOld里面                            self.listOld.append(value)                        else:                            #相对路径的话就在前面加上http://songshuhui.net                            self.listOld.append('http://songshuhui.net/' + value)                #提取harf中img标签的src的值                else:                    #从href里面提取出img的src。根据=分割后的第一个值,去掉最后一个字符">"                    self.listOld.append(value.split("=")[1][0:len(value.split("=")[1])-1])        elif tag == 'link':            # 判断标签<link>的属性            for name,value in attrs:                if name =='href' and value!= '':                    #如果是绝对路径                    if value.find('http')>-1:                        self.listOld.append(value)                    else:                    #如果是相对路径                        self.listOld.append('http://songshuhui.net/'+value)        elif tag == 'img':            # 判断标签<img>的属性            for name,value in attrs:                if name == 'src' and value!= '':                    #如果是绝对路径                    if value.find('http')>-1:                        self.listOld.append(value)                    #如果是相对路径                    else:                        self.listOld.append('http://songshuhui.net/'+value)        elif tag == 'form':            # 判断标签<form>的属性            for name,value in attrs:                #提取form的action属性值                if name == 'action' and value!='':                    self.listOld.append(value)        elif tag == 'div':            # 判断标签<form>的属性            for name,value in attrs:                #提取div的onclick属性值,以'为分隔,的第一个值,并且包含http                if name == 'onclick' and value != '' and value.find('http')>-1:                    #print "测试onclick的值:"+value.split('\'')[1]                    #结果加入到listOld中                    self.listOld.append(value.split('\'')[1])if __name__ == '__main__':    #获取源代码    fileA=open('songshuhui[1].txt')    a=fileA.read()    my = MyParser()       # 传入要分析的数据,也就是科学松鼠会首页     my.feed(a)    d={}    #这里是去重    for urls in my.listOld:        if not d.has_key(urls):            d[urls]=""    nlst=[]    for key in d.keys():        nlst.append(key)    #创建SSH.txt,把最终去重后的结果逐行写入    fileB=open('SSHurl.txt','w')    for urlstr in nlst:        fileB.write(urlstr + '\n')    print 'OK!'    #清理工作    fileB.close()    fileA.close()

posted @ 2010-05-25 11:09  Phenix.  阅读(2346)  评论(0编辑  收藏  举报