使用python抓取网站

时间:2011-07-20 22:40:14

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

所以我正在寻找一种动态的方式来抓取网站并从每个页面获取链接。我决定尝试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循环更加动态。提前感谢任何见解。

5 个答案:

答案 0 :(得分:4)

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

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

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

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

答案 1 :(得分: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并在以后从每个链接获取HTML代码...

答案 2 :(得分:0)

要从评论中回答你的问题,这是一个例子(它是红宝石,但我不知道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

抱歉红宝石,但它是一种更好的语言:P并且不应该很难适应,或者像我说的那样理解。

答案 3 :(得分:0)

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

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

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

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

答案 4 :(得分:0)

使用scrapy

  

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