내 웹 크롤러의 문제와 파이썬에 대한 urlparse 플러그인을 보내고 있습니다. 내 코드는 기본적으로 블룸버그 (Bloomberg)와 같은 특정 도메인을 크롤링하고 모든 HTML을 내 데스크톱으로 다운로드합니다. 아직 초기 단계에 있으므로 오류 등이 있음을 알게 될 것입니다. (저는 파이썬을 처음 사용합니다.)웹 크롤러 오류 : "AttributeError : 스파이더 인스턴스가 '발견'에는 속성이 없습니다"
특정 문제는 reconstruct_url
과 관련이 있습니다. 나는 urlparse.urljoin(a,b)
기능을 개별적으로 테스트했으며 기대했던대로 작동하지만이 클래스에서는이 기능이 마음에 들지 않습니다. 어떤 사람이 여기에 문제가 무엇인지 보여줄 수 있습니까? 다른 문제뿐만 아니라 그들을 밖으로 소리 주시기 바랍니다 내 코드에서 당신에게 눈부시게 명백한 경우
이 전체 프로그램을 작성에서 내 첫 번째 시도이다. 비록 이것이 비교적 초기 단계에 있음을 유의하십시오. 어떤 도움을 주셔서 감사합니다.
#note: <meta content='Story' property='bb:resource_type'>
import urllib2
import os
from bs4 import BeautifulSoup
from urlparse import urljoin
class Spider:
links_to_crawl = []
crawled_links = []
ignored_links = ['/']
domain = 'http://bloomberg.com/'
#meta type = ('meta', {'property','bb:resource_type'})['content']=='Story'
# append all starting link to links_to_crawl
def __init__(self, url):
print 'Spider initialising...'
self.links_to_crawl.append(url)
# open input url and return html
def grab_html(self,url):
open_url = self.urllib2.urlopen(url)
data = open_url.read()
open_url.close()
return data
# return title from input html for file naming and ensure
# no '/' present in title.
def get_title(self, data=''):
title_start = data.find('<title>')+7
title_end = data.find('</title>')-1
title = data[title_start:title_end]
title = title.translate(None, '/')
return title+".txt"
# return date from input html for file saving structure
def get_date(self, data=''):
soup = self.BeautifulSoup(data)
# try statement to avoid error when meta tag combinations
# not found.
try:
date = soup.find('meta', {'name':'pubdate'})['content']
return date[:12] # !! only tested with bloomberg.com !!
# if there is no published date, return 'Other'
except TypeError:
return 'Other'
# if link is relative url return 'Rel' or
# if url is allowed domain return 'Abs', else False.
def url_type(self,url=''):
if url[0:4] != 'http':
return 'Rel'
elif url.find(self.domain) != -1:
return 'Abs'
else:
return False
# reconstruct relative url
def reconstruct_url(self, page='', rel=''):
print page #debug
print rel #debug
print self.urljoin(page, rel) #debug
return self.urljoin(page, rel)
# get all links in input html and append to links_to_crawl
# unless in crawled_links or ignored_links
# if link is relative url reconstruct url and append to
# links_to_crawl, append relative url to ignored_links
def get_links(self, data=''):
soup = self.BeautifulSoup(data)
for link in soup.find_all('a'):
# try statement to avoid error when finding
# <a> tags withou 'href'
try:
if link['href'] in self.ignored_links or self.crawled_links:
pass
else:
if self.url_type(link['href'])=='Rel':
reconstructed_link = self.reconstruct_url(self.domain, link['href']) #to change !!!!!!!!!!!!!!!!!
self.links_to_crawl.append(reconstructed_link) # append reconstructed link to links_to_crawl
self.ignored_links.append(link['href']) # append original link to ignored_links
else:
self.links_to_crawl.append(link['href'])
except KeyError:
pass
# if directory exists do nothing
# if directory does not exist write directory
def ensure_dir(self, directory=''):
if self.os.path.exists(directory):
pass
else:
self.os.makedirs(directory)
# ensure the html being saved is the type requested
# currently only compatible with 1 meta type
def ensure_meta_type(self, data=''):
soup = self.BeautifulSoup(data)
try:
soup.find('meta', {'property':'bb:resource_type'})['content']=='Story'
print 'True'
return True
except TypeError:
print 'False'
return False
# save input html to txt file on mac os desktop and return
# absolute path to file
def save_html(self,data=''):
if self.ensure_meta_type(data):
print 'SAVING URL'
# allocate save path for file and ensure save path exists
save_path = self.os.path.abspath('/Users/sampeka/Desktop/Python Spider'+'/'+self.get_date(data))
self.ensure_dir(save_path)
# get file name and write file to absolute path
file_name = self.get_title(data)
absolute_path = save_path+'/'+file_name
opened_file = open(absolute_path,'w')
opened_file.write(data)
opened_file.close()
else:
pass
# crawl links_to_crawl and pop to crawled_links list
# if ValueError then pop to ignored_links
# except urllib2.URLError to avoid web crawler crawling
# non-url links
def crawl_links(self):
while len(self.links_to_crawl) > 0:
url = self.links_to_crawl[0]
print url
try:
data = self.grab_html(url)
self.get_links(data)
self.save_html(data)
self.crawled_links.append(self.links_to_crawl.pop(0))
except (ValueError, self.urllib2.URLError):
self.ignored_links.append(self.links_to_crawl.pop(0))
print 'Spider finished.'
print 'Ignored links:'
print self.ignored_links
print 'Crawled links:'
print self.crawled_links
spider = Spider('http://www.bloomberg.com/news')
spider.crawl_links()
코드를 약간 닦았습니다. – twil
대단히 감사합니다 :) –