I am trying to scrape some data from https://www.officialcharts.com/ by parallelising web requests using asyncio/aiohttp. I implemented the code given at the link here.
I followed two different procedures. The first one goes like this.
from bs4 import BeautifulSoup from urllib.request import urlopen from selenium import webdriver import time import pandas as pd import numpy as np import re import json import requests from bs4 import BeautifulSoup from datetime import date, timedelta from IPython.display import clear_output import memory_profiler import spotipy import spotipy.util as util import pandas as pd from more_itertools import unique_everseen weeks = [] d = date(1970, 1, 1) d += timedelta(days = 6 - d.weekday()) for i in range(2500): weeks.append(d.strftime('%Y%m%d')) d += timedelta(days = 7) import asyncio from aiohttp import ClientSession import nest_asyncio nest_asyncio.apply() result = [] async def fetch(url, session): async with session.get(url) as response: return await response.read() async def run(r): tasks = [] # Fetch all responses within one Client session, # keep connection alive for all requests. async with ClientSession() as session: for i in range(r): url = 'https://www.officialcharts.com/charts/singles-chart/' + weeks[i] + '/' task = asyncio.ensure_future(fetch(url, session)) tasks.append(task) responses = await asyncio.gather(*tasks) result.append(responses) loop = asyncio.get_event_loop() future = asyncio.ensure_future(run(5)) loop.run_until_complete(future) print('Done') print(result[0][0] == None) The problem with above code is, it fails when I make more than simultaneous 1000 requests.
The author of the post implemented a different procedure to address this issue and he claims we can do as many as 10K requests. I followed along his second procedure and here is my code for that.
import random import asyncio from aiohttp import ClientSession import nest_asyncio nest_asyncio.apply() result = [] async def fetch(url, session): async with session.get(url) as response: delay = response.headers.get("DELAY") date = response.headers.get("DATE") print("{}:{} with delay {}".format(date, response.url, delay)) return await response.read() async def bound_fetch(sem, url, session): # Getter function with semaphore. async with sem: await fetch(url, session) async def run(r): tasks = [] # create instance of Semaphore sem = asyncio.Semaphore(1000) # Create client session that will ensure we dont open new connection # per each request. async with ClientSession() as session: for i in range(r): url = 'https://www.officialcharts.com/charts/singles-chart/' + weeks[i] + '/' task = asyncio.ensure_future(bound_fetch(sem, url, session)) tasks.append(task) responses = await asyncio.gather(*tasks) result.append(responses) number = 5 loop = asyncio.get_event_loop() future = asyncio.ensure_future(run(number)) loop.run_until_complete(future) print('Done') print(result[0][0] == None) For some reason, this doesn't return any responses.
PS:I am not from CS background and just program for fun. I have no clue what's going on inside the asyncio code.