【问题标题】:Robots.txt being read, but not being followedRobots.txt 被读取,但未被关注
【发布时间】:2015-09-06 19:03:32
【问题描述】:

这是我的爬虫代码,我相信我基本上拥有我需要的所有组件,有些可能只是乱序,我知道正在读取 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'])

【问题讨论】:

    标签: python-3.x beautifulsoup web-crawler robots.txt


    【解决方案1】:

    更新:基于 cmets。包括一组保存收集的所有唯一 URL

    并不是机器人解析器失败了。这是您的 visited 数组,当您附加到它时。

    您实际上希望将 visited.append(link['href']) 移到 try/except 块之后,而是使用您刚刚访问的 URL 作为传递的值 » 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)
    

    这样,您只有在成功抓取 URL 后才会追加。此外,当您检查是否已抓取该 URL 时,它会检查相应的 URL 集。

    我还更改了for 循环中的if 语句。它使用提取的链接来检查是否已访问。

    【讨论】:

    • 我知道你要去哪里,它确实有效。问题是我希望能够打印出我总共拥有的网址列表。不解释是我的错。但我想确保它只抓取我稍后放回循环时能够遵循的网址。
    • @Dakotabartell,我不确定我是否完全按照。但我的印象是,您想要一份您在抓取期间收集的所有链接(即 URL)的列表?如果是这种情况,您可能希望创建一个包含该信息的第三个数组,并将其放置在 visited 数组曾经位于 for 循环中的位置。对于爬虫来说,有一个队列很常见,你可以像使用 urls 那样推送和弹出队列,但也有一个数据结构来保存你收集的数据。
    • @Dakotabartell 我已经更新了上面的代码块。我不确定这是否满足您的要求。您可以通过再次调用parse.can_fetchfor 循环的if 语句添加逻辑以检查link['href'] 是否可抓取,但我认为这有点矫枉过正。无论如何,您都将在 while 循环中执行此操作,并且不会产生太多额外费用,因为您不会针对无法导航到的 URL 访问 urllib.request
    • 我不知道为什么,但更多不允许的链接正在通过。基本上我需要的是将href链接从页面中剥离出来,在它附加url列表之前,它会通过检查robots.txt来运行它,看看它是否被允许。我将在我的原始帖子中放入一些伪代码以获得一些指导。
    • 基本上当我打印 url 时,我不希望有任何在禁止列表中的链接
    猜你喜欢
    • 2023-03-15
    • 1970-01-01
    • 2015-11-12
    • 1970-01-01
    • 2013-10-06
    • 2015-12-02
    • 1970-01-01
    • 1970-01-01
    • 2022-08-10
    相关资源
    最近更新 更多