【问题标题】:Optimization of this Python code - webscraping and output results to CSV file此 Python 代码的优化 - 网页抓取并将结果输出到 CSV 文件
【发布时间】:2016-07-06 15:35:26
【问题描述】:

我正在尝试从几千页中抓取数据。我的代码在大约 100 页上运行良好,但随后速度急剧下降。我很确定我的类似泰山的代码可以改进,从而提高网络抓取过程的速度。任何帮助,将不胜感激。蒂亚!

这里是简化的代码:

csvfile=open('test.csv', 'w', encoding='cp850', errors='replace')
writer=csv.writer(csvfile)

list_url= ["http://www.randomsite.com"]
i=1

for url in list_url:
 base_url_parts = urllib.parse.urlparse(url)
 while True:
    raw_html = urllib.request.urlopen(url).read()
    soup = BeautifulSoup(raw_html, "lxml")
    
    #### scrape the page for the desired info 

    i=i+1
    n=str(i)

   #Zip the data
    output_data=zip(variable_1, variable_2, variable_3, ..., variable_10)

#Write the observations to the CSV file
    writer=csv.writer(open('test.csv','a',newline='', encoding='cp850', errors='replace'))
    writer.writerows(output_data)
    csvfile.flush()
    
    base="http://www.randomsite.com/page"
    base2=base+n
    url_part2="/otherstuff"
    url_test = base2+url_part2
    
    try:
       if url_test != None:
           url = url_test
           print(url)
       else:
           break
    except: 
       break

csvfile.close()

编辑:感谢所有的答案,我从他们身上学到了很多东西。我正在(慢慢地!)学习如何使用 Scrapy。但是,我发现这些页面可以通过批量下载获得,这将是解决性能问题的更好方法。

【问题讨论】:

标签: python csv web-scraping beautifulsoup


【解决方案1】:

主要瓶颈是您的代码是同步的(阻塞)。在完成对当前 URL 的处理之前,您不会进入下一个 URL。

您需要通过切换到开箱即用地解决此问题的Scrapy 或通过例如grequests 自己构建一些东西来实现异步操作。

【讨论】:

  • 感谢您指出scrapy;从我所见,它似乎很有希望(对于未来没有批量下载的项目)。
【解决方案2】:

如果您想在没有大量复杂代码的情况下快速运行,您需要 A) 将请求与解析分离(因为解析会阻塞您原本用来发出请求的线程),以及 B)同时发出请求并同时解析它们。所以,我会做几件事:

  1. 使用小事件异步请求所有页面。我一直在努力使用 Python 中的异步 http 框架,并发现 eventlet 最容易学习。
  2. 每次成功获取页面时,将 html 存储在某处。 A)您可以将其写入本地的单个 html 文件,但您手上会有很多文件。 B)您可能可以将这么多记录存储为字符串(str(source_code))并将它们放在本机数据存储中,只要它经过哈希处理(可能是集合或字典)​​。 C)您可以使用超轻量级但不是特别高性能的数据库,如 TinyDB,并将页面源代码粘贴在 JSON 文件中。 D) 您可以使用第三方库的数据结构进行高性能计算,例如 Pandas DataFrame 或 NumPy 数组。他们可以很容易地存储这么多数据,但可能有点矫枉过正。
  3. 在检索到每个文档后分别对其进行解析。使用 lxml 进行解析将非常快,因此根据您需要多快的速度,您可能能够按顺序解析文件。如果您想更快,请查看有关 python 中的多处理的教程。它非常容易学习,而且您可以同时解析 X 个文档,其中 X 是您机器上可用内核的数量。

【讨论】:

  • 谢谢。如果时间允许,我一定会回复您的建议。
【解决方案3】:

也许这只是简化中的一个错误,但看起来您多次打开“test.csv”,但只关闭一次。不确定当 URL 数量超过 100 时,这是否是导致意外减速的原因,但如果您希望所有数据都放在一个 csv 文件中,您可能应该坚持打开文件并在顶部打开一次写入器,就像您一样已经在做,而不是在循环内做。

另外,在构造新 URL 的逻辑中:url_test != None 不总是正确的吗?那么你是如何退出循环的呢? urlopen 失败时的例外情况?那么你应该尝试一下。这不是性能问题,但任何形式的清晰度都会有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多