如何使用 For Loop 从 html 中获取多个链接?
How do I use For Loop to get multiple links from an html?
这是我目前拥有的:
import bs4
import requests
def getXkcdComic(comicUrl):
for i in range(0,20):
res = requests.get(comicUrl + str(1882 - i))
res.raise_for_status()
soup = bs4.BeautifulSoup(res.text, 'html.parser')
img = soup.select_one("div#comic > img")
return str(img['src'])
link = getXkcdComic('https://xkcd.com/')
print(link)
我解析 html,得到一个 link,第一个,因为我知道 url 在 1882 结束,下一个我想要的是 1881,所以我写了这个for-loop
得到其余的。
它只打印一个结果,就好像没有写循环一样。
奇怪的是,如果我减少 return
函数的缩进,它会 returns 一个不同的 url.
我还不太明白 For-loops
是如何工作的。
另外,这是我第一次 post 来这里,所以请原谅我的英语和无知。
你的函数returns一旦遇到return
语句就把控制权交给调用者,这里是for的第一次迭代.
您可以在函数中 yield
而不是 return
以从函数中连续生成图像链接并保持 for 循环 运行 :
import bs4
import requests
def getXkcdComic(comicUrl):
for i in range(0,20):
...
yield img['src'] # <- here
# make a list of links yielded by function
links = list(getXkcdComic('https://xkcd.com/'))
参考文献:
Understanding Generators in Python
第一次点击 return
语句时,函数将转到 return,无论您是否处于循环中。因此,您的 for()
循环将到达第一次迭代的结尾,请参阅 return
,仅此而已。其他 19 次迭代不会 运行.
如果您缩减 return
,您得到不同 URL 的原因是您的 for()
循环现在可以 运行 完成。但是由于您没有保存之前的任何迭代,因此它将 return 仅保存最后一个。
您可能想要的是构建一个结果列表,return。
def getXkcdComic(comicUrl):
images = [] # Create an empty list for results
for i in range(0,20):
res = requests.get(comicUrl + str(1882 - i))
res.raise_for_status()
soup = bs4.BeautifulSoup(res.text, 'html.parser')
img = soup.select_one("div#comic > img")
images.append(str(img['src'])) # Save the result by adding it to the list
return images # Return the list
请记住,您的外部范围中的 link
实际上是一个 列表 链接,并相应地处理它。
当您在第一个循环中调用 'return' 时,整个 'getXkcdComic' 函数退出并且 returns.
像这样的东西可能会像原始代码一样工作和打印:
import bs4
import requests
def getXkcdComic(comicUrl, number):
res = requests.get(comicUrl + str(number))
res.raise_for_status()
soup = bs4.BeautifulSoup(res.text, 'html.parser')
return str(soup.select_one("div#comic > img")['src'])
link = 'https://xkcd.com/'
for i in range(20):
print(getXkcdComic(link, 1882-i))
您希望如何通过单个方法调用获得多个输出(此处为 url)? for 循环可以帮助您多次迭代一个范围并获得多个结果,但只有在您进行一次调用之前它没有用处。您可以执行以下操作之一:
- 与其在方法内编写循环,不如在循环中调用方法。这样每次调用都会打印您的输出。
- 将整个内容写在方法中,以便您有多个打印语句。
执行以下操作:
def getXkcdComic(comicUrl):
for i in range(0,20):
res = requests.get(comicUrl + str(1882 - i))
res.raise_for_status()
soup = bs4.BeautifulSoup(res.text, 'html.parser')
img = soup.select_one("div#comic > img")
print str(img['src'])
getXkcdComic('https://xkcd.com/')
发生这种情况是因为您在循环中创建了 return
。试一试:
def getXkcdComic(comicUrl):
res = list()
for i in range(0,20):
res = requests.get(comicUrl + str(1882 - i))
res.raise_for_status()
soup = bs4.BeautifulSoup(res.text, 'html.parser')
img = soup.select_one("div#comic > img")
res.append(str(img['src']))
return res
你可以改变这个:
for i in range(0,20):
res = requests.get(comicUrl + str(1882 - i))
对此:
for i in range(1862, 1883, 1):
res = requests.get(comicUrl + str(i))
其他答案都很好,也很笼统,但对于这个特定案例,还有更好的方法。 xkcd提供了JSONAPI,所以可以使用列表理解:
def getXkcdComic(comicUrl):
return [requests.get(comicUrl + str(1882 - i) + '/info.0.json').json()['img']
for i in range(0,20)]
这对 xkcd 服务器也更快、更友好。
这是我目前拥有的:
import bs4
import requests
def getXkcdComic(comicUrl):
for i in range(0,20):
res = requests.get(comicUrl + str(1882 - i))
res.raise_for_status()
soup = bs4.BeautifulSoup(res.text, 'html.parser')
img = soup.select_one("div#comic > img")
return str(img['src'])
link = getXkcdComic('https://xkcd.com/')
print(link)
我解析 html,得到一个 link,第一个,因为我知道 url 在 1882 结束,下一个我想要的是 1881,所以我写了这个for-loop
得到其余的。
它只打印一个结果,就好像没有写循环一样。
奇怪的是,如果我减少 return
函数的缩进,它会 returns 一个不同的 url.
我还不太明白 For-loops
是如何工作的。
另外,这是我第一次 post 来这里,所以请原谅我的英语和无知。
你的函数returns一旦遇到return
语句就把控制权交给调用者,这里是for的第一次迭代.
您可以在函数中 yield
而不是 return
以从函数中连续生成图像链接并保持 for 循环 运行 :
import bs4
import requests
def getXkcdComic(comicUrl):
for i in range(0,20):
...
yield img['src'] # <- here
# make a list of links yielded by function
links = list(getXkcdComic('https://xkcd.com/'))
参考文献:
Understanding Generators in Python
第一次点击 return
语句时,函数将转到 return,无论您是否处于循环中。因此,您的 for()
循环将到达第一次迭代的结尾,请参阅 return
,仅此而已。其他 19 次迭代不会 运行.
如果您缩减 return
,您得到不同 URL 的原因是您的 for()
循环现在可以 运行 完成。但是由于您没有保存之前的任何迭代,因此它将 return 仅保存最后一个。
您可能想要的是构建一个结果列表,return。
def getXkcdComic(comicUrl):
images = [] # Create an empty list for results
for i in range(0,20):
res = requests.get(comicUrl + str(1882 - i))
res.raise_for_status()
soup = bs4.BeautifulSoup(res.text, 'html.parser')
img = soup.select_one("div#comic > img")
images.append(str(img['src'])) # Save the result by adding it to the list
return images # Return the list
请记住,您的外部范围中的 link
实际上是一个 列表 链接,并相应地处理它。
当您在第一个循环中调用 'return' 时,整个 'getXkcdComic' 函数退出并且 returns.
像这样的东西可能会像原始代码一样工作和打印:
import bs4
import requests
def getXkcdComic(comicUrl, number):
res = requests.get(comicUrl + str(number))
res.raise_for_status()
soup = bs4.BeautifulSoup(res.text, 'html.parser')
return str(soup.select_one("div#comic > img")['src'])
link = 'https://xkcd.com/'
for i in range(20):
print(getXkcdComic(link, 1882-i))
您希望如何通过单个方法调用获得多个输出(此处为 url)? for 循环可以帮助您多次迭代一个范围并获得多个结果,但只有在您进行一次调用之前它没有用处。您可以执行以下操作之一:
- 与其在方法内编写循环,不如在循环中调用方法。这样每次调用都会打印您的输出。
- 将整个内容写在方法中,以便您有多个打印语句。
执行以下操作:
def getXkcdComic(comicUrl):
for i in range(0,20):
res = requests.get(comicUrl + str(1882 - i))
res.raise_for_status()
soup = bs4.BeautifulSoup(res.text, 'html.parser')
img = soup.select_one("div#comic > img")
print str(img['src'])
getXkcdComic('https://xkcd.com/')
发生这种情况是因为您在循环中创建了 return
。试一试:
def getXkcdComic(comicUrl):
res = list()
for i in range(0,20):
res = requests.get(comicUrl + str(1882 - i))
res.raise_for_status()
soup = bs4.BeautifulSoup(res.text, 'html.parser')
img = soup.select_one("div#comic > img")
res.append(str(img['src']))
return res
你可以改变这个:
for i in range(0,20):
res = requests.get(comicUrl + str(1882 - i))
对此:
for i in range(1862, 1883, 1):
res = requests.get(comicUrl + str(i))
其他答案都很好,也很笼统,但对于这个特定案例,还有更好的方法。 xkcd提供了JSONAPI,所以可以使用列表理解:
def getXkcdComic(comicUrl):
return [requests.get(comicUrl + str(1882 - i) + '/info.0.json').json()['img']
for i in range(0,20)]
这对 xkcd 服务器也更快、更友好。