python - 在 python 抓取器中使用装饰器时遇到问题

标签 python python-3.x function web-scraping decorator

我用 python 编写了一个脚本,通过从它的登录页面跟踪基本链接来获取一些帖子的链接。如果我坚持传统方法,我自己也可以刮掉同样的东西。

不过,我的目标是使用 decorator 实现同样的效果。看起来我已经接近了,但是在将链接从函数 get_links() 传递到 get_target_link() 时,我遇到了困难。我使用 return func() 作为函数 get_target_link() 中的占位符,因为我不知道如何传递链接。函数 get_links() 中有打印语句(如果未注释则有效)以确保我在正确的轨道上。

我如何将 return linklistget_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/

相关文章:

python - 如何检查日期是否早于今天的日期

Python 多个子正则表达式

javascript - 函数返回错误值并且其中一个字符是意外的

python - 优雅地处理可变数量的输入和输出文件

python - 处理 pandas DF 中的重复索引

python - 实现字典函数来计算列表的平均值

python - Django 1.7 抛出 django.core.exceptions.AppRegistryNotReady : Models aren't loaded yet

python - sklearn中的加权聚类

javascript - 我应该将 "document.getElementById("").innerHTML = "";"放在我的 Javascript 中的哪里?

c++ - 如何通过对构造函数的引用传递对象