在网络爬虫中解析 HTML 页面

Parsing HTML page in web crawler

提问人:zahlen 提问时间:8/18/2017 最后编辑:zahlen 更新时间:8/18/2017 访问量:1152

问:

我正在尝试构建一个网络爬虫,该爬虫可以抓取页面上的所有链接并将它们添加到文件中。

我的 Python 代码包含一个执行以下操作的方法:-

  1. 打开给定的网页(使用 urllib2 模块)

  2. 检查 HTTP 标头 Content-Type 是否包含 text/html

  3. 将原始 HTML 响应转换为可读代码,并将其存储到html_string变量中。

  4. 然后,它创建一个 Link_Finder 类的实例,该实例采用属性 base url(Spider_url) 和 page url(page_url)。Link_Finder在另一个模块link_finder.py中定义。
  5. 然后使用 feed 函数将html_string馈送到类中。

下面将详细解释Link_Finder类。

def gather_links(page_url):     #page_url is relative url
        html_string=''
        try :
            req=urllib2.urlopen(page_url)
            head=urllib2.Request(page_url)
            if 'text/html' in head.get_header('Content-Type'):              
                html_bytes=req.read()
                html_string=html_bytes.decode("utf-8")
            finder=LinkFinder(Spider.base_url,page_url)
            finder.feed(html_string)            
        except Exception as e:
            print "Exception " + str(e)
            return set()
        return finder.page_links()

link_finder.py 模块使用标准的 Python、HTMLParserurlparse 模块。类 Link_Finder 继承自 HTMLParser 并重写 handle_starttag 函数以获取所有带有 href 属性的 a 标签,并将 url 添加到 set(self.queue) 中

from HTMLParser import HTMLParser 
import urlparse     
class LinkFinder(HTMLParser):
    def __init__(self,base_url,page_url):       #page_url is relative url 
        super(LinkFinder,self).__init__()      
        self.base_url=base_url
        self.page_url=page_url
        self.links=set()
    def handle_starttag(self,tag,attrs):    #Override default handler methods
        if tag==a:
            for(key,value) in attrs:
                if key=='href':
                    url=urlparse.urljoin(self.base_url,value) #Get exact url
                    self.links.add(url)
    def error(self,message):
        pass
    def page_links(self):     #return set of links
        return self.links

我收到异常

“NoneType”类型的参数不可迭代

我认为问题出在我使用 urllib2 请求检查标头内容的方式上。 我对此有点陌生,所以一些解释会很好

python-2.7 网络爬虫 html 解析 urllib2

评论

0赞 user6399774 8/18/2017
完整的错误输出可能会好得多。

答:

0赞 user6399774 8/18/2017 #1

我会像这样使用 BeautifulSoup 而不是 HTMLParser -

soup = BeautifulSoup(pageContent)
links = soup.find_all('a')