【问题标题】:How can I reduce the number of requests and use only one?如何减少请求数量并仅使用一个?
【发布时间】:2019-03-02 18:57:25
【问题描述】:

我的程序是这样做的:

  1. 从我的网站获取 XML
  2. 运行所有的 URL
  3. 通过请求从我的网页(SKU、名称、标题、价格等)获取数据
  4. 通过将相同 SKU 的价格与请求进行比较,从另一个网站获取最低价格。

我在每个 def 上都使用了很多请求:

def get_Price (SKU):
    check ='https://www.XXX='+SKU
    r = requests.get(check)
    html = requests.get(r.url)
    bsObj = BeautifulSoup(html.content,'html.parser')
    return Price

def get_StoreName (SKU):
    check ='https://XXX?keyword='+SKU
    r = requests.get(check)
    html = requests.get(r.url)
    bsObj = BeautifulSoup(html.content,'html.parser')
    return storeName

def get_h1Tag (u):
    html = requests.get(u)
    bsObj = BeautifulSoup(html.content,'xml')
    h1 = bsObj.find('h1',attrs={'itemprop':'name'}).get_text()
    return h1

如何减少对 URL 的请求或连接的数量 - 并在整个程序中使用一个请求或一个连接?

【问题讨论】:

  • 澄清一下,您是想减少对特定位置(都获得相同内容)还是对具有不同 URL 的一台服务器的请求数量? “到 URL”听起来像前者,“一个连接整个程序”像后者
  • 嗨,因为我是 python 的新手——我已经在我想要的每个参数上构建了 def——我可以一次得到所有的东西吗?它会减少我的处理时间吗?
  • 您的多个请求中的 URL 是否相同?如果是,那么下面的答案效果很好,如果不是,它只会增加额外的事情要做。

标签: python-3.x beautifulsoup python-requests


【解决方案1】:

我假设这是一个脚本,其中包含您按特定顺序调用的一组方法。 如果是这样,这是dict 的一个很好的用例。我会编写一个函数来记住对 URL 的调用。

然后您可以在其他函数中重复使用此函数:

requests_cache = {}

def get_url (url, format_parser):
    if url not in requests_cache:
        r = requests.get(url)
        html = requests.get(r.url)
        requests_cache[url] = BeautifulSoup(html.content, format_parser)
    return requests_cache[url]

def get_Price (makat):
    url = 'https://www.zap.co.il/search.aspx?keyword='+makat
    bsObj = get_url(url, 'html.parser')
    # your code to find the price
    return zapPrice

def get_zapStoreName (makat):
    url = 'https://www.zap.co.il/search.aspx?keyword='+makat
    bsObj = get_url(url, 'html.parser')
    # your code to find the store name
    return storeName

def get_h1Tag (u):
    bsObj = get_url(u, 'xml')
    h1 = bsObj.find('h1',attrs={'itemprop':'name'}).get_text()
    return h1

如果要避免使用全局变量,还可以将requests_cache 设置为get_url 的属性或定义中的默认参数。后者还允许您通过传递一个空的dict 来绕过缓存。

同样,这里的假设是您定期将此代码作为脚本运行。在这种情况下,每次运行程序时,requests_cache 都会被清除。

但是,如果这是较大程序的一部分,您可能希望定期“使”缓存“过期”,否则每次都会得到相同的结果。

【讨论】:

  • 嗨,谢谢。是的 - 我定期运行脚本。但我在我的站点地图中的所有 url 上运行它。所以 requests_cache 在这里很好吗?如果我会使用它 - 缓存不会是上次请求的数据?
  • 嗨。 requests_cache 应该是好的。缓存将包含对同一 url 上的同一请求的响应。对不同 url 或不同参数的请求不会相互覆盖。每次运行程序时,requests_cache 都会重新初始化。所以,每次运行程序都会得到新的数据
  • 太棒了! :) 谢谢 。现在我需要让程序运行得更快...:)
【解决方案2】:

这是requests-cache 库的一个很好的用例。示例:

from requests_cache import CachedSession

# Save cached responses in a SQLite file (scraper_cache.sqlite), and expire after 6 minutes
session = CachedSession('scraper_cache.sqlite', expire_after=360)

def get_Price (SKU):
    check ='https://www.XXX='+SKU
    r = session.get(check)
    html = session.get(r.url)
    bsObj = BeautifulSoup(html.content,'html.parser')
    return Price

def get_StoreName (SKU):
    check ='https://XXX?keyword='+SKU
    r = session.get(check)
    html = session.get(r.url)
    bsObj = BeautifulSoup(html.content,'html.parser')
    return storeName

def get_h1Tag (u):
    html = session.get(u)
    bsObj = BeautifulSoup(html.content,'xml')
    h1 = bsObj.find('h1',attrs={'itemprop':'name'}).get_text()
    return h1

除此之外:无论是否使用requests-cache,只要您重复调用同一主机,使用会话都是一种很好的做法,因为它使用连接池:https://docs.python-requests.org/en/latest/user/advanced/#session-objects

【讨论】:

    猜你喜欢
    • 2019-02-08
    • 2021-05-07
    • 1970-01-01
    • 2011-12-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多