我用 python 编写了一个脚本,通过从它的登录页面跟踪基本链接来获取一些帖子的链接。如果我坚持传统方法,我自己也可以刮掉同样的东西。
不过,我的目标是使用 decorator
实现同样的效果。看起来我已经接近了,但是在将链接从函数 get_links()
传递到 get_target_link()
时,我遇到了困难。我使用 return func()
作为函数 get_target_link()
中的占位符,因为我不知道如何传递链接。函数 get_links()
中有打印语句(如果未注释则有效)以确保我在正确的轨道上。
我如何将 return linklist
从 get_links()
传递到 get_target_link()
以便我可以必要时重新使用它们?
这是我到目前为止尝试过的:
import requests
from urllib.parse import urljoin
from bs4 import BeautifulSoup
url = "https://www.janglo.net/component/option,com_sobi2/"
def get_links(func):
linklist = []
res = requests.get(func())
soup = BeautifulSoup(res.text,"lxml")
for item in soup.select(".sobi2ItemTitle a"):
linklist.append(urljoin(url,item.get("href")))
#print(linklist)
return linklist
def get_target_link():
return func() #All I need to do is fix this line
return get_target_link
@get_links
def get_info():
res = requests.get(url)
soup = BeautifulSoup(res.text,"lxml")
for items in soup.select("#sobi2CatListSymbols .sobi2SubcatsListItems a[title]"):
if items.text=="Tutors":
ilink = f"{urljoin(url,items.get('href'))}"
return ilink
if __name__ == '__main__':
for links in get_info():
print(links)
Post Script:我只想遵守我在上面尝试应用的逻辑
。
@sir Andersson 的更新(你能解释一下你想如何在必要时重新使用它们吗
):
def get_target_link():
titles = []
new_links = func()
for new_link in new_links:
res = requests.get(new_link)
soup = BeautifulSoup(res.text)
titles.append(soup.select_one("h1").text)
return titles
return get_target_link
我想创建装饰函数来像下面的@Carlos Mermingas:
import requests
from urllib.parse import urljoin
from bs4 import BeautifulSoup
url = "https://www.janglo.net/component/option,com_sobi2/"
def get_info(link):
res = requests.get(url)
soup = BeautifulSoup(res.text,"lxml")
for items in soup.select("#sobi2CatListSymbols .sobi2SubcatsListItems a[title]"):
if items.text=="Tutors":
ilink = f"{urljoin(url,items.get('href'))}"
return ilink
def get_links(tlink):
linklist = []
res = requests.get(tlink)
soup = BeautifulSoup(res.text,"lxml")
for item in soup.select(".sobi2ItemTitle a"):
linklist.append(urljoin(url,item.get("href")))
return linklist
def get_target_link(link):
titles = []
res = requests.get(link)
soup = BeautifulSoup(res.text,"lxml")
titles.append(soup.select_one("h1").text)
return titles
if __name__ == '__main__':
item = get_info(url)
for nlink in get_links(item):
for ititle in get_target_link(nlink):
print(ititle)
最佳答案
有点长的帖子,老实说,我已经停止阅读你的第一个 python 错误。
让我为您修复它,然后您告诉我这是否是缺失的。这就是装饰器模式在 Python 中的工作方式。
一开始有点奇怪,有点像海运船运送海运船,但它很聪明。
装饰器是返回要调用的函数而不是另一个函数的函数。
让我们想象一下这个函数,没有修饰。
>>> def some_func(number):
... return f'Number is {number}'
...
>>> print(some_func(10))
Number is 10
为了修饰这个函数,假设我们要添加模糊测试;在这里和那里添加一些延迟是很常见的事情。
>>> def fuzz():
... def fuzz_decorator(func):
... def fuzz_wrapper(*args, **kwargs):
... print('fuzz') # this is our added functionality
... return func(*args, **kwargs) # call whatever we're decorating
... return fuzz_wrapper
... return fuzz_decorator
...
>>> @fuzz()
... def some_func(number):
... return f'Number is {number}'
...
>>> print(some_func(10))
fuzz
Number is 10
fuzz()
是一个函数,它返回一个接受函数fuzz_decorator(func)
的函数,并返回一个为func 添加一些功能的新函数
,同时在某个时候调用 func
本身。
希望这不会造成混淆。但是你错了。
关于python - 在 python 抓取器中使用装饰器时遇到问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53557307/