用Python爬取网站
我想找一种动态的方法来爬取一个网站,并从每个页面上抓取链接。我决定试试BeautifulSoup这个工具。这里有两个问题:第一,我想知道怎么能比用嵌套的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
为了回答你在评论中的问题,这里有一个例子(虽然是用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 而且应该不难适应,或者像我说的那样,理解起来也不会太困难。
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)
对于frame标签也是这样。对于“img src”和“a href”标签也是如此。我很喜欢这个话题——也许是我哪里搞错了……编辑:当然有一个顶层实例,它会保存网址,并在之后从每个链接获取HTML代码……
4
在一个网站上爬取所有链接的问题是一个常见的问题。如果你在谷歌上搜索“爬虫 网站 python”,你会找到一些可以帮你完成这个任务的库。这里有一个我找到的:
http://pypi.python.org/pypi/spider.py/0.5
更棒的是,谷歌还找到了这个问题,已经在StackOverflow上有人问过并得到了解答: