मैं किसी पृष्ठ पर जावास्क्रिप्ट प्रस्तुत करने के लिए अनुरोध HTML का उपयोग कर रहा हूं। मैं प्रक्रिया को तेज करने के लिए concurrent.futures का भी उपयोग कर रहा हूं। मेरा कोड पूरी तरह से काम कर रहा था जब तक कि मैंने निम्नलिखित पंक्ति नहीं जोड़ी:
response.html.render(timeout=60, sleep=1, wait=3, retry=10)
जिस पर मुझे त्रुटि मिली:
response.html.render(timeout=60, sleep=1, wait=3, retries=10)
फ़ाइल "C:\Users\Ze\Anaconda3\lib\site-packages\requests_html.py", लाइन 586, रेंडर में self.browser = self.session.browser # स्वचालित रूप से एक ईवेंट लूप और ब्राउज़र बनाएं
फ़ाइल "C:\Users\Ze\Anaconda3\lib\site-packages\requests_html.py", लाइन 727, ब्राउजर में self.loop = asyncio.get_event_loop()
फ़ाइल "C:\Users\Ze\Anaconda3\lib\asyncio\events.py", लाइन 639, में get_event_loop RuntimeError बढ़ाएँ ('थ्रेड% r में कोई वर्तमान ईवेंट लूप नहीं है।' RuntimeError: थ्रेड में कोई वर्तमान ईवेंट लूप नहीं है 'थ्रेडपूल एक्ज़ीक्यूटर-0_0'।
अगर मैं समस्याग्रस्त रेखा को नीचे के खंड में ले जाता हूं तो यह फिर से काम करता है, लेकिन फिर प्रतिपादन समानांतर में नहीं हो रहा है, है ना?
for result in concurrent.futures.as_completed(futures):
result = result.result()
समस्या का कारण क्या है? मैंने कभी भी एसिंक्सियो का उपयोग नहीं किया है। क्या मुझे इसके लिए करना होगा? क्या इसे लागू करना आसान है?
आपका बहुत बहुत धन्यवाद!
कोड:
def load_page_and_extract_items(url):
response = session.get(url, headers=get_headers())
# render javascript
response.html.render(timeout=60, wait=3)
source = BeautifulSoup(response.html.raw_html, 'lxml')
def get_pages(remaining_urls):
with concurrent.futures.ThreadPoolExecutor() as executor:
# for each of 60 possible pages
for current_page_number in range(60):
futures = [executor.submit(load_page_and_extract_items, url) for url in remaining_urls]
for result in concurrent.futures.as_completed(futures):
result = result.result()
def main():
get_pages(urls)
1 उत्तर
यह सीधे सवाल का जवाब नहीं देता है लेकिन मल्टीथ्रेडेड वेब-स्क्रैपिंग के लिए एक तकनीक का प्रदर्शन करता है जो मेरे परीक्षणों में अच्छा प्रदर्शन करता है। यह मूल प्रश्न में बताए गए URL का उपयोग कर रहा है और कुछ ऐसे टैग की खोज करता है जिनमें HREF शामिल हैं और फिर उन URL को संसाधित करते हैं। सामान्य विचार यह है कि मैं सत्रों का एक पूल बनाता हूं और प्रत्येक थ्रेड को पूल (एक कतार) से सत्र ऑब्जेक्ट मिलता है, इसका उपयोग करता है और फिर इसे कतार में वापस रखता है जिससे यह अन्य धागे के लिए उपलब्ध हो जाता है।
from requests_html import HTMLSession
import concurrent.futures
import queue
QUEUE = queue.Queue()
def makeSessions(n=4):
for _ in range(n):
QUEUE.put(HTMLSession())
def cleanup():
while True:
try:
getSession(False).close()
except queue.Empty:
break
def getSession(block=True):
return QUEUE.get(block=block)
def freeSession(session):
if isinstance(session, HTMLSession):
QUEUE.put(session)
def getURLs():
urls = []
session = getSession()
try:
response = session.get('https://www.aliexpress.com')
response.raise_for_status()
response.html.render()
for a in response.html.xpath('//dt[@class="cate-name"]/span/a'):
if 'href' in a.attrs:
urls.append(a.attrs['href'])
finally:
freeSession(session)
return urls
def processURL(url):
print(url)
session = getSession()
try:
response = session.get(url)
response.raise_for_status()
response.html.render()
finally:
freeSession(session)
if __name__ == '__main__':
try:
makeSessions()
with concurrent.futures.ThreadPoolExecutor() as executor:
futures = [executor.submit(processURL, url) for url in getURLs()]
for _ in concurrent.futures.as_completed(futures):
pass
finally:
cleanup()
संबंधित सवाल
नए सवाल
python
पायथन एक बहु-प्रतिमान है, गतिशील रूप से टाइप किया हुआ, बहुउद्देशीय प्रोग्रामिंग भाषा है। यह एक साफ और एक समान वाक्यविन्यास सीखने, समझने और उपयोग करने के लिए त्वरित होने के लिए डिज़ाइन किया गया है। कृपया ध्यान दें कि अजगर 2 आधिकारिक तौर पर 01-01-2020 के समर्थन से बाहर है। फिर भी, संस्करण-विशिष्ट पायथन सवालों के लिए, [अजगर -२.०] या [अजगर -३.x] टैग जोड़ें। पायथन वेरिएंट (जैसे, ज्योथन, PyPy) या लाइब्रेरी (उदा।, पांडस और न्यूमपी) का उपयोग करते समय, कृपया इसे टैग में शामिल करें।