I'm trying to open a file with 5 million entries in Python
My code needs to fetch inputs line by line in order (a difference of a few tens of lines with ThreadPoolExecutor is not a problem) and then be fetched by ThreadPoolExecutor to send to get_url function
Maybe the url variable is getting too big, ThreadPoolExecutor should itself retrieve them one by one from the file by keeping a line counter? I already tried to do this but failed (this is the first time I use ThreadPoolExecutor)
with open("1_1.txt") as stream:
urls = [line.strip() for line in stream]
with ThreadPoolExecutor(max_workers=50) as pool:
pool.map(get_url, urls)
The full code of my script :
import requests
from concurrent.futures import ThreadPoolExecutor
import fileinput
from bs4 import BeautifulSoup
import traceback
from threading import Thread
from requests.packages.urllib3.exceptions import InsecureRequestWarning
import warnings
from random import random
from queue import Queue
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
warnings.filterwarnings("ignore", category=UserWarning, module='bs4')
count_requests = 0
host_error = 0
def get_url(url):
global queue
global count_requests
global host_error
try:
result_request = requests.get(url, verify=False, timeout=40)
soup = BeautifulSoup(result_request.text, 'html.parser')
title = soup.title.get_text().splitlines(False)
title = str(title)
title = title[0:10000]
count_requests = count_requests + 1
queue.put(f'{url} - {title} \n')
except:
queue.put(f'FAILED : {url} \n')
host_error = host_error + 1
# dedicated file writing task
def file_writer(filepath, queue):
global count_requests
# open the file
with open(filepath, 'a', encoding="utf-8") as file:
# run until the event is set
while True:
# get a line of text from the queue
line = queue.get()
# check if we are done
if line is None:
# exit the loop
break
# write it to file
file.write(line)
# flush the buffer
file.flush()
# mark the unit of work complete
queue.task_done()
# mark the exit signal as processed, after the file was closed
queue.task_done()
# create the shared queue
queue = Queue()
# defile the shared file path
filepath = 'output.txt'
# create and start the file writer thread
writer_thread = Thread(target=file_writer, args=(filepath,queue), daemon=True)
writer_thread.start()
# wait for all tasks in the queue to be processed
queue.join()
with open("1_1.txt") as stream:
urls = [line.strip() for line in stream]
with ThreadPoolExecutor(max_workers=1) as pool:
pool.map(get_url, urls)