【问题标题】:Use python to crawl a website使用python爬取一个网站
【发布时间】:2011-10-09 19:24:42
【问题描述】:

所以我正在寻找一种动态的方式来抓取网站并从每个页面中获取链接。我决定尝试 Beauitfulsoup。两个问题:如何更动态地执行此操作,然后使用嵌套的 while 语句搜索链接。我想从该站点获取所有链接。但是我不想继续放嵌套的while循环。

    topLevelLinks = self.getAllUniqueLinks(baseUrl)
    listOfLinks = list(topLevelLinks)       

    length = len(listOfLinks)
    count = 0       

    while(count < length):

        twoLevelLinks = self.getAllUniqueLinks(listOfLinks[count])
        twoListOfLinks = list(twoLevelLinks)
        twoCount = 0
        twoLength = len(twoListOfLinks)

        for twoLinks in twoListOfLinks:
            listOfLinks.append(twoLinks)

        count = count + 1

        while(twoCount < twoLength):
            threeLevelLinks = self.getAllUniqueLinks(twoListOfLinks[twoCount])  
            threeListOfLinks = list(threeLevelLinks)

            for threeLinks in threeListOfLinks:
                listOfLinks.append(threeLinks)

            twoCount = twoCount +1



    print '--------------------------------------------------------------------------------------'
    #remove all duplicates
    finalList = list(set(listOfLinks))  
    print finalList

无论如何,我的第二个问题是要告诉我是否从该站点获得了所有链接。请原谅我,我对 python 有点陌生(一年左右),我知道我的一些过程和逻辑可能很幼稚。但我必须以某种方式学习。主要是我只想更动态地执行此操作,然后使用嵌套的 while 循环。提前感谢您提供任何见解。

【问题讨论】:

  • 为什么不使用一个数组作为所有链接的累加器,然后在网站上找到更多信息时将它们排队?
  • 好的,好主意。我将如何继续找到更多。上面的代码只在页面树中向下三层。我想让这个更动态,然后嵌套 while 循环
  • 你不需要嵌套。通过页面的 html 运行一次,并拥有所有链接的数组。然后通过下一个链接。除非你想做深度优先,否则为什么不使用递归函数,虽然最终它会溢出堆栈......网络很大:O

标签: python nested while-loop hyperlink web-crawler


【解决方案1】:

爬取网站并获取所有链接的问题是一个常见问题。如果您在 Google 上搜索“spider web site python”,您可以找到可以为您执行此操作的库。这是我找到的一个:

http://pypi.python.org/pypi/spider.py/0.5

更好的是,Google 发现这个问题已经在 StackOverflow 上提出并回答了:

Anyone know of a good Python based web crawler that I could use?

【讨论】:

  • 我最初确实在 StackOverflow 上看过那篇文章,并决定使用 BeautifulSoup + urllib2。但主要问题是如何使这些嵌套的 while 循环更加动态。我会看看spider.py。感谢您的信息
【解决方案2】:

如果使用 BeautifulSoup,为什么不使用 findAll() 方法?基本上,在我的爬虫中我会这样做:

self.soup = BeautifulSoup(HTMLcode)
for frm in self.soup.findAll(str('frame')):
try:
    if not frm.has_key('src'):
        continue
    src = frm[str('src')]
    #rest of URL processing here
except Exception, e:
    print  'Parser <frame> tag error: ', str(e)

用于框架标签。 “img src”和“a href”标签也是如此。 不过我喜欢这个话题-也许是我在这里做错了…… 编辑:有一个顶级实例,它保存 URL 并稍后从每个链接中获取 HTMLcode...

【讨论】:

    【解决方案3】:

    从评论中回答你的问题,这里有一个例子(它在 ruby​​ 中,但我不知道 python,它们很相似,你可以很容易地理解):

    #!/usr/bin/env ruby
    
    require 'open-uri'
    
    hyperlinks = []
    visited = []
    
    # add all the hyperlinks from a url to the array of urls
    def get_hyperlinks url
      links = []
      begin
        s = open(url).read
        s.scan(/(href|src)\w*=\w*[\",\']\S+[\",\']/) do
          link = $&.gsub(/((href|src)\w*=\w*[\",\']|[\",\'])/, '')
          link = url + link if link[0] == '/'
    
          # add to array if not already there
          links << link if not links =~ /url/
        end
      rescue
        puts 'Looks like we can\'t be here...'
      end
      links
    end
    
    print 'Enter a start URL: '
    hyperlinks << gets.chomp
    puts 'Off we go!'
    count = 0
    while true
      break if hyperlinks.length == 0
      link = hyperlinks.shift
      next if visited.include? link
      visited << link
      puts "Connecting to #{link}..."
      links = get_hyperlinks(link)
      puts "Found #{links.length} links on #{link}..."
      hyperlinks = links + hyperlinks
      puts "Moving on with #{hyperlinks.length} links left...\n\n"
    end
    

    对 ruby​​ 感到抱歉,但它是一种更好的语言 :P 并且应该不难适应,或者,就像我说的,理解。

    【讨论】:

      【解决方案4】:

      1) 在 Python 中,我们不计算容器的元素并使用它们来索引;我们只是迭代它的元素,因为这是我们想要做的。

      2)要处理多级链接,我们可以使用递归。

      def followAllLinks(self, from_where):
          for link in list(self.getAllUniqueLinks(from_where)):
              self.followAllLinks(link)
      

      这不处理链接循环,但原始方法也没有。您可以通过构建一个已访问链接的set 来处理这个问题。

      【讨论】:

      • 我将如何使用您提交的这种方法构建一组已访问过的链接。这是在正确的轨道上。非常感谢
      【解决方案5】:

      使用scrapy:

      Scrapy 是一种快速的高级屏幕抓取和网络抓取 框架,用于抓取网站并从中提取结构化数据 他们的页面。它可以用于广泛的目的,从数据 挖掘到监控和自动化测试。

      【讨论】:

        猜你喜欢
        • 2015-09-19
        • 2017-09-12
        • 2019-05-04
        • 2012-09-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多