Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/295.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/url/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/flash/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何使用BeautifulSoup提取网站中的所有URL_Python_Url_Web Scraping_Beautifulsoup_Web Crawler - Fatal编程技术网

Python 如何使用BeautifulSoup提取网站中的所有URL

Python 如何使用BeautifulSoup提取网站中的所有URL,python,url,web-scraping,beautifulsoup,web-crawler,Python,Url,Web Scraping,Beautifulsoup,Web Crawler,我正在做一个项目,需要从网站上提取所有链接, 使用此代码,我将从单个URL获取所有链接: import requests from bs4 import BeautifulSoup, SoupStrainer source_code = requests.get('https://stackoverflow.com/') soup = BeautifulSoup(source_code.content, 'lxml') links = [] for link in soup.find_all

我正在做一个项目,需要从网站上提取所有链接, 使用此代码,我将从单个URL获取所有链接:

import requests
from bs4 import BeautifulSoup, SoupStrainer

source_code = requests.get('https://stackoverflow.com/')
soup = BeautifulSoup(source_code.content, 'lxml')
links = []

for link in soup.find_all('a'):
    links.append(str(link))
问题是,若我想提取所有URL,我必须编写另一个for循环,然后再编写另一个。 我想提取这个网站和这个网站的子域中存在的所有URL。 有没有办法不写嵌套的?
即使编写嵌套的for,我也不知道应该使用多少for来获取所有URL。

好吧,实际上你所要求的是可能的,但这意味着一个无限循环将一直运行,直到你的内存
boooom

无论如何,这个想法应该如下所示

  • 您将对汤中的项目使用
    。findAll('a')
    然后
    item.get('href')

  • 添加到
    set
    以消除重复的URL,如果
    
    条件
    不是None
    以除去
    None
    对象

  • 然后不断循环,直到你的
    集合
    变成
    0
    某个东西 像
    len(URL)


    • 哇,找到解决方案大约需要30分钟, 我找到了一种简单有效的方法, 正如@αԋɱҽԃ-αєιcαη所提到的,如果你的网站链接到谷歌等大型网站,它不会停止,直到你的内存充满数据。 所以有一些步骤你应该考虑。

    • 做一个while循环来搜索你的网站以提取所有的URL
    • 使用异常处理来防止崩溃
    • 删除重复项并分隔URL
    • 设置URL数量的限制,例如找到1000个URL时
    • 循环时停止,以防止电脑内存变满
    • 这里是一个示例代码,它应该可以正常工作,我实际测试了它,对我来说很有趣:

      import requests
      from bs4 import BeautifulSoup
      import re
      import time
      
      source_code = requests.get('https://stackoverflow.com/')
      soup = BeautifulSoup(source_code.content, 'lxml')
      data = []
      links = []
      
      
      def remove_duplicates(l): # remove duplicates and unURL string
          for item in l:
              match = re.search("(?P<url>https?://[^\s]+)", item)
              if match is not None:
                  links.append((match.group("url")))
      
      
      for link in soup.find_all('a', href=True):
          data.append(str(link.get('href')))
      flag = True
      remove_duplicates(data)
      while flag:
          try:
              for link in links:
                  for j in soup.find_all('a', href=True):
                      temp = []
                      source_code = requests.get(link)
                      soup = BeautifulSoup(source_code.content, 'lxml')
                      temp.append(str(j.get('href')))
                      remove_duplicates(temp)
      
                      if len(links) > 162: # set limitation to number of URLs
                          break
                  if len(links) > 162:
                      break
              if len(links) > 162:
                  break
          except Exception as e:
              print(e)
              if len(links) > 162:
                  break
      
      for url in links:
      print(url)
      
      我将限制设置为162,您可以根据需要任意增加它,并且允许内存。

      这是怎么回事

      import re,requests
      from simplified_scrapy.simplified_doc import SimplifiedDoc 
      source_code = requests.get('https://stackoverflow.com/')
      doc = SimplifiedDoc(source_code.content.decode('utf-8')) # incoming HTML string
      lst = doc.listA(url='https://stackoverflow.com/') # get all links
      for a in lst:
        if(a['url'].find('stackoverflow.com')>0): #sub domains
          print (a['url'])
      
      你也可以使用这个爬行框架,它可以帮助你做很多事情

      from simplified_scrapy.spider import Spider, SimplifiedDoc
      class DemoSpider(Spider):
        name = 'demo-spider'
        start_urls = ['http://www.example.com/']
        allowed_domains = ['example.com/']
        def extract(self, url, html, models, modelNames):
          doc = SimplifiedDoc(html)
          lstA = doc.listA(url=url["url"])
          return [{"Urls": lstA, "Data": None}]
      
      from simplified_scrapy.simplified_main import SimplifiedMain
      SimplifiedMain.startThread(DemoSpider())
      

      这回答了你的问题吗?不,不是。另外,这个问题的答案不再有效,因为从那时起,BeautifulSoup发生了变化。@Mona好吧,所以你需要使用stackoverflow的
      API
      。这是你第二次删除你的答案了,:(((我需要一个适用于所有网站的算法。这不是我问题的答案,例如stackoverflow中有超过10000000个问题,我需要一个代码来提取所有存在的URL,包括stackoverflow所有帖子的URL等等。你能给我一个代码来知道如何实现这个想法吗?@Mona这需要你来实现。)你自己去做。因为你需要使用
      try/except
      timeout
      threading
      。很多事情!如果
      href
      持有
      url
      的路径,比如
      /file1/file2/
      ,那就需要
      f
      字符串。就像
      f“www.site.com/{url}
      还有太多其他需要他/她自己发展的事情需要关注。@aԋ625;ҽaԃєιcαηI谷歌关于ram的使用关于这个问题,使用12GB的ram,你可以存储大约128849018个URL(每个URL 100个字符)在你的ram中作为一个变量,所以我认为这不会是一个问题。@Ali好吧,那么你将永远运行你的程序并等待它完成。因为你所说的for循环运行没有线程,而线程只使用一个变量,就像一只老鼠在不停地运行和停止一样。但是有了线程,情况就不同了。非常感谢你。你节省了时间我的日子:)很长,有点脏的代码,但正如你所说,它工作得很好。@mona不客气,如果你在这个社区提问之前用谷歌搜索了你的问题,你应该已经找到了解决方案,顺便说一句,很乐意帮忙。等等,
      remove\u duplicates()怎么了
      ?!为什么不提取url并将其放在一个集合中?@alexander-cécile是的,我的代码很糟糕,我有点忙,所以我明天会编辑它,并检查
      如果len(链接)>162
      ,我这样做是为了在每一步之后检查这个条件,我知道这是没有必要的。@alexander-cécile如果你有额外的时间,我会很高兴你编辑我的答案,否则我会在以后编辑它。
      from simplified_scrapy.spider import Spider, SimplifiedDoc
      class DemoSpider(Spider):
        name = 'demo-spider'
        start_urls = ['http://www.example.com/']
        allowed_domains = ['example.com/']
        def extract(self, url, html, models, modelNames):
          doc = SimplifiedDoc(html)
          lstA = doc.listA(url=url["url"])
          return [{"Urls": lstA, "Data": None}]
      
      from simplified_scrapy.simplified_main import SimplifiedMain
      SimplifiedMain.startThread(DemoSpider())