这是我的抓取工具的代码,我相信我基本上拥有了我需要的所有组件,有些可能只是乱序,我知道robots.txt正在被读取。不幸的是,它仍在吐出不应该访问的网址。有人能帮助我吗?
import urllib.request
import urllib.parse
from bs4 import BeautifulSoup
import re
import urllib.robotparser
url = "http://www.imdb.com"
urls = [url]
visited =[]
robotsUrl = url +'/robots.txt'
from multiprocessing import Process, Manager
while len(urls) < 1000:
parse = urllib.robotparser.RobotFileParser()
parse.set_url(robotsUrl)
parse.read()
if parse.can_fetch('*',urls[0]):
try:
htmltext = urllib.request.urlopen(urls[0]).read()
except:
print (urls[0])
soup = BeautifulSoup(htmltext, "html.parser")
urls.pop(0)
print(len(urls))
for link in soup.findAll('a', href=True):
link['href'] = urllib.parse.urljoin(url,link['href'])
if url in link['href'] not in visited:
urls.append(link['href'])
visited.append(link['href'])
print (visited)
伪代码:
for link in soup.findAll('a', href=True):
link['href'] = urllib.parse.urljoin(url,link['href'])
#something like if parse.can_fetch('*',link['href']):
if url in link['href'] not in visited:
urls.append(link['href'])
visited.append(link['href'])
答案 0 :(得分:1)
更新:根据评论。包含一个用于保存所有唯一网址
的集合并不是机器人解析器失败了。它是你的visited
数组,当你追加它时。
您实际上想要在try / except块之后将visited.append(link['href'])
移到右侧,而是使用刚刚访问过的网址作为传递值»visited.append(urls[0])
。
import urllib.request
import urllib.parse
from bs4 import BeautifulSoup
import re
import urllib.robotparser
url = "http://www.imdb.com"
queue = [url]
visited =[]
unique = set([])
robotsUrl = url +'/robots.txt'
from multiprocessing import Process, Manager
while len(queue) < 1000:
parse = urllib.robotparser.RobotFileParser()
parse.set_url(robotsUrl)
parse.read()
if parse.can_fetch('*',queue[0]):
try:
htmltext = urllib.request.urlopen(queue[0]).read()
except:
print (queue[0])
visited.append(queue[0])
soup = BeautifulSoup(htmltext, "html.parser")
queue.pop(0)
print(len(queue))
for link in soup.findAll('a', href=True):
link['href'] = urllib.parse.urljoin(url,link['href'])
if link['href'] not in visited:
queue.append(link['href'])
unique.add(link['href'])
print("visited: ", visited)
print("uniques: ", unique)
这样,只有在您成功抓取网址后才会追加。此外,当您检查是否已经抓取了网址时,它会检查相应的网址集。
我还更改了if
循环中的for
语句。它使用提取的链接来检查已访问。