【问题标题】:What is the best way to optimize this for loop for speed? (pandas, BS objects.)优化此 for 循环以提高速度的最佳方法是什么? (熊猫,BS对象。)
【发布时间】:2020-12-05 01:25:26
【问题描述】:

我有一个 pandas 数据框/系列,每行都有一个 URL,用于从内部创建一个 Beautiful Soup 对象并从内部抓取数据。但是,循环非常慢,运行我当前的循环需要很多小时才能完成,因为有超过 21,000 行。这可以通过apply或numpy进行优化吗?

count = 0
url = data['review_link']


for link in url:
    url = "http://{}".format(link)
    req = requests.get(url)
    best = BeautifulSoup(req.text, 'html')
    
    reviews = best.find_all('div', {'class' : 'review-detail'})
    
    for review in reviews:

        entry = {
            'artist' : safeFindText(review, 'ul', {'class' : 'artist-links artist-list single-album-tombstone__artist-links'}),
            'bnm' : safeFindText(review, 'p', {'class' : 'bnm-txt'}),
            'title' : safeFindText(review, 'h1', {'class' : 'single-album-tombstone__review-title'}),
            'score' : safeFindText(review, 'span', {'class' : 'score'}),
            'label' : safeFindText(review, 'li', {'class' : 'labels-list__item'}),
            'year' : safeFindText(review, 'span', {'class' : 'single-album-tombstone__meta-year'}),
            'author' : safeFindText(review, 'a', {'class' : 'authors-detail__display-name'}),
            'author_title' : safeFindText(review, 'span', {'class' : 'authors-detail__title'}),
            'genre' : safeFindText(review, 'a', {'class' : 'genre-list__link'}),
            'review_timestamp' : safeFindText(review, 'time', {'class' : 'pub-date'}),
            'review_abstract' : safeFindText(review, 'div', {'class' : 'review-detail__abstract'}),
            'review_text' : safeFindText(review,'div', {'class' : 'clearfix flex-md'})
            
            
                                   }
        pitchfork_dicts.append(entry)
        if count % 10 == 0:
            print("{} rows completed".format(count))
    count += 1

【问题讨论】:

  • 实际循环可能不是瓶颈,.apply 不会产生明显的差异,实际上,它可能会稍微慢一些。 req = requests.get(url) 可能是瓶颈,而不是循环数据帧。或者可能是safeFindText 中发生的任何事情。也不清楚你将如何在这里使用numpy,看起来你只是从网站中提取文本数据,numpy 是用于以多维数组、线性代数等数字运算表示的代码
  • 如果这是您的瓶颈,您可以同时向 API 发出多个请求。

标签: python pandas beautifulsoup


【解决方案1】:

问题是您的程序在请求等待响应时处于空闲状态。由于等待网络 IO 可能是瓶颈,我不认为 apply 或 numpy 会给你带来很大的加速。我能想到的两个优化是使用一个 ThreadPool 来处理所有请求,而你的主循环遍历它的列表。或者使用 async 异步发出请求,以便在等待响应时,您可以继续处理列表。

对于线程池,您可以创建主线程推送到的线程安全队列。然后是一个线程池,它会弹出下一项并发出请求并处理结果。

【讨论】:

    猜你喜欢
    • 2019-03-07
    • 1970-01-01
    • 1970-01-01
    • 2022-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多