Фон:
Я хочу отслеживать 100 URL-адресов (сделайте снимок и сохраните его, если контент отличается от предыдущего), мой план заключается в использовании urllib.request для сканирования их каждые x минут, скажем x = 5, без остановок.
Поэтому я не могу использовать сингл для цикла и сна, так как я хочу начать обнаружение для ULR1, а затем начать URL2 почти одновременно.
while TRUE:
for url in urlList:
do_detection()
time.sleep(sleepLength)
Поэтому я должен использовать пул? Но я должен ограничить поток небольшим количеством, которое может обрабатывать мой процессор (не может установить 100 потоков, если у меня есть 100 ULR)
Мой вопрос:
Даже я могу отправить 100 URL-адресов в свой список в ThreadPool (4) с четырьмя потоками, как я должен конструировать для управления каждым потоком для обработки URL-адреса 100/4 = 25, поэтому нитки исследуют URL1, sleep (300) перед следующим зондом к URL1, а затем сделать URL2.... ULR25 и вернуться к URL1...? Я не хочу ждать 5 минут * 25 для полного цикла.
Код Psuedo или примеры будут большой помощью! Я не могу найти или подумать, как заставить looper() и детектор() вести себя по мере необходимости?
(Я думаю, что как отказаться от нескольких html-страниц параллельно с beautifulsoup в python? Это близкий, но не точный ответ)
Может быть, что-то вроде этого для каждого потока? Я попытаюсь разобраться, как разбить 100 элементов на каждый поток. using pool.map(func, iterable [, chunksize]) принимает список, и я могу установить chunksize на 25.
def one_thread(Url):
For url in Url[0:24]:
CurrentDetect(url)
if 300-timelapsed>0:
remain_sleeping=300-timtlapsed
else:
remain_sleeping=0
sleep (remain_sleeping)
For url in Url[0:24]:
NextDetect()
Нерабочий код, который я пытаюсь написать:
import urllib.request as req
import time
def url_reader(url = "http://stackoverflow.com"):
try
f = req.urlopen(url)
print (f.read())
except Exception as err
print (err)
def save_state():
pass
return []
def looper (sleepLength=720,urlList):
for url in urlList: #initial save
Latest_saved.append(save_state(url_reader(url))) # return a list
while TRUE:
pool = ThreadPool(4)
results = pool.map(urllib2.urlopen, urls)
time.sleep(sleepLength) # how to parallel this? if we have 100 urls, then takes 100*20 min to loop?
detector(urlList) #? use last saved status returned to compare?
def detector (urlList):
for url in urlList:
contentFirst=url_reader(url)
contentNext=url_reader(url)
if contentFirst!=contentNext:
save_state(contentFirst)
save_state(contentNext)
Вам необходимо установить запросы,
pip install requests
если вы хотите использовать следующий код:
# -*- coding: utf-8 -*-
import concurrent.futures
import requests
import queue
import threading
# URL Pool
URLS = [
# Put your urls here
]
# Time interval (in seconds)
INTERVAL = 5 * 60
# The number of worker threads
MAX_WORKERS = 4
# You should set up request headers
# if you want to better evade anti-spider programs
HEADERS = {
'Accept': '*/*',
'Accept-Encoding': 'gzip, deflate',
'Accept-Language': 'en-US,en;q=0.9',
'Cache-Control': 'max-age=0',
'Connection': 'keep-alive',
#'Host': None,
'If-Modified-Since': '0',
#'Referer': None,
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.62 Safari/537.36',
}
############################
def handle_response(response):
# TODO implement your logics here !!!
raise RuntimeError('Please implement function 'handle_response'!')
# Retrieve a single page and report the URL and contents
def load_url(session, url):
#print('load_url(session, url={})'.format(url))
response = session.get(url)
if response.status_code == 200:
# You can refactor this part and
# make it run in another thread
# devoted to handling local IO tasks,
# to reduce the burden of Net IO worker threads
return handle_response(response)
def ThreadPoolExecutor():
return concurrent.futures.ThreadPoolExecutor(max_workers=MAX_WORKERS)
# Generate a session object
def Session():
session = requests.Session()
session.headers.update(HEADERS)
return session
# We can use a with statement to ensure threads are cleaned up promptly
with ThreadPoolExecutor() as executor, Session() as session:
if not URLS:
raise RuntimeError('Please fill in the array 'URLS' to start probing!')
tasks = queue.Queue()
for url in URLS:
tasks.put_nowait(url)
def wind_up(url):
#print('wind_up(url={})'.format(url))
tasks.put(url)
while True:
url = tasks.get()
# Work
executor.submit(load_url, session, url)
threading.Timer(interval=INTERVAL, function=wind_up, args=(url,)).start()