python - 如何优化网页抓取代码片段以使其运行速度更快?

标签 python web-scraping

我编写了这段代码,它当前正在运行,正在抓取大量数据。到目前为止,循环已经运行了 800 次。它必须运行约 16,000 次才能获取所有数据。

一般来说,我如何优化网页抓取代码,或者我是否受到 requests.get 的摆布?

import json
import requests
import pandas as pd
from pandas.io.json import json_normalize

headers = {}
p = {}

a = int(p['page'])
df = pd.DataFrame()
while True:
    p['page'] = str(a)
    try:
        a += 1
        r = requests.get('URL',headers=headers, params=p)
        complete_json = r.json()
        print('success')
        df_data = pd.DataFrame.from_dict(json_normalize(complete_json['explore_vintage']['matches']), orient='columns')
        df = df.append(df_data)

    except:
        False

df.to_excel('output.xlsx', encoding='utf8')
df.to_csv("output.csv")
print(df.head)

最佳答案

我可以立即看到一些优化。

您可以在此处添加的第一件事是通过异步请求进行并行处理。 requests 库是同步的,正如您所看到的 - 它将阻塞,直到每个页面完全处理。有number of libraries 请求项目officially recommends 。如果您走这条路,您将需要更明确地定义终止条件,而不是无限 while 循环内的 try/ except block 。

这都是主要从他们的示例中提取的伪代码,但您可以看到它是如何工作的:

from requests_futures.sessions import FuturesSession
from concurrent.futures import as_completed
import json
import time

def response_hook(resp, *args, **kwargs):
    with open(f'tmp/{time.thread_time_ns()}.json', 'wb') as fp:
        parsed = resp.json()
        fp.write(json.dumps(parsed).encode('utf-8'))


futures_session = FuturesSession()
futures_session.hooks['response'] = response_hook


with futures_session as session:
    futures = [
        session.get(f'https://jsonplaceholder.typicode.com/todos/{i}', hooks={'response': response_hook}) for i in range(16000)
    ]
    for future in as_completed(futures):
        resp = future.result()

将数据解析为数据帧是一个明显的瓶颈。随着数据帧变得越来越大,目前速度将继续减慢。我不知道这些 JSON 响应的大小,但如果您要获取 16k 响应,我想一旦您耗尽了内存,这就会很快停止。如果可能的话,我建议将抓取和转换操作解耦。将所有抓取的数据保存到它们自己的独立 JSON 文件中(如上例所示)。如果单独保存每个响应并且抓取完成,您可以循环遍历所有保存的内容,解析它们,然后输出到 Excel 和 CSV。请注意,根据 JSON 文件的大小,您可能仍然会遇到内存问题,但至少不会阻止抓取过程,并且可以单独处理输出处理。

关于python - 如何优化网页抓取代码片段以使其运行速度更快?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59915322/

相关文章:

python - 为什么 MlabSceneModel 的 light_manager 没有设置?

python - `to_datetime` 限制或误用?值错误: Doesn't match format specified

python - 在Python中使用Beautifulsoup和Urllib2,如何找到特定标签包围的数据?

Python 网络抓取 : dealing with user login popup

jquery - 使用 node.js 抓取时使用 jQuery 访问 CSS 值

javascript - 如何在 Python 3 中使用请求从使用 JavaScript 和 jQuery 的网站获取数据

python - 如何将列向量组合成矩阵

python - 设置 Pandas 列时提高性能

r - 使用 R 进行网页抓取和循环浏览页面

python - 在 PyQt5 TreeView 中拖放?