Python 如何使用BeautifulSoup提取网站中的所有URL
我正在做一个项目,需要从网站上提取所有链接, 使用此代码,我将从单个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
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')
- 添加到
以消除重复的URL,如果set
条件
以除去不是None
对象None
- 然后不断循环,直到你的
变成集合
某个东西 像0
len(URL)
- 做一个while循环来搜索你的网站以提取所有的URL
- 使用异常处理来防止崩溃
- 删除重复项并分隔URL
- 设置URL数量的限制,例如找到1000个URL时
- 循环时停止,以防止电脑内存变满 这里是一个示例代码,它应该可以正常工作,我实际测试了它,对我来说很有趣:
- 哇,找到解决方案大约需要30分钟,
我找到了一种简单有效的方法,
正如@αԋɱҽԃ-αєιcαη所提到的,如果你的网站链接到谷歌等大型网站,它不会停止,直到你的内存充满数据。
所以有一些步骤你应该考虑。
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())