मैं यह समाधान स्वीकार करूंगा कि यह समाधान फ़ायरफ़ॉक्स प्रोफाइल सेव करने के लिए थोड़ा और हैकी है, लेकिन यह क्रोम और फ़ायरफ़ॉक्स दोनों में काम करता है, और ब्राउज़र-विशिष्ट सुविधा पर निर्भर नहीं है जो किसी भी समय बदल सकता है । और यदि कुछ और नहीं है, तो शायद यह किसी को भविष्य की चुनौतियों को हल करने के तरीके पर थोड़ा अलग परिप्रेक्ष्य देगा।
किसी और चीज की: सुनिश्चित करें कि आप सेलेनियम है और स्थापित pyvirtualdisplay ...
- अजगर 2:
sudo pip install selenium pyvirtualdisplay
- अजगर 3:
sudo pip3 install selenium pyvirtualdisplay
जादू
import pyvirtualdisplay
import selenium
import selenium.webdriver
import time
import base64
import json
root_url = 'https://www.google.com'
download_url = 'https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png'
print('Opening virtual display')
display = pyvirtualdisplay.Display(visible=0, size=(1280, 1024,))
display.start()
print('\tDone')
print('Opening web browser')
driver = selenium.webdriver.Firefox()
#driver = selenium.webdriver.Chrome() # Alternately, give Chrome a try
print('\tDone')
print('Retrieving initial web page')
driver.get(root_url)
print('\tDone')
print('Injecting retrieval code into web page')
driver.execute_script("""
window.file_contents = null;
var xhr = new XMLHttpRequest();
xhr.responseType = 'blob';
xhr.onload = function() {
var reader = new FileReader();
reader.onloadend = function() {
window.file_contents = reader.result;
};
reader.readAsDataURL(xhr.response);
};
xhr.open('GET', %(download_url)s);
xhr.send();
""".replace('\r\n', ' ').replace('\r', ' ').replace('\n', ' ') % {
'download_url': json.dumps(download_url),
})
print('Looping until file is retrieved')
downloaded_file = None
while downloaded_file is None:
# Returns the file retrieved base64 encoded (perfect for downloading binary)
downloaded_file = driver.execute_script('return (window.file_contents !== null ? window.file_contents.split(\',\')[1] : null);')
print(downloaded_file)
if not downloaded_file:
print('\tNot downloaded, waiting...')
time.sleep(0.5)
print('\tDone')
print('Writing file to disk')
fp = open('google-logo.png', 'wb')
fp.write(base64.b64decode(downloaded_file))
fp.close()
print('\tDone')
driver.close() # close web browser, or it'll persist after python exits.
display.popen.kill() # close virtual display, or it'll persist after python exits.
Explaination
हम पहले डोमेन हम से एक फ़ाइल डाउनलोड लक्षित कर रहे हैं पर एक URL को लोड। यह हमें cross site scripting समस्याओं में भाग दिए बिना, उस डोमेन पर AJAX अनुरोध करने की अनुमति देता है।
अगला, हम डीओएम में कुछ जावास्क्रिप्ट इंजेक्शन कर रहे हैं जो AJAX अनुरोध को बंद कर देता है। एक बार AJAX अनुरोध एक प्रतिक्रिया देता है, हम प्रतिक्रिया लेते हैं और इसे एक फ़ाइल रीडर ऑब्जेक्ट में लोड करते हैं। वहां से हम readAsDataUrl() को कॉल करके फ़ाइल की बेस 64 एन्कोडेड सामग्री निकाल सकते हैं। इसके बाद हम बेस 64 एन्कोडेड सामग्री ले रहे हैं और इसे window
पर जोड़ रहे हैं, जो एक वैश्विक रूप से सुलभ चर है।
अंत में, क्योंकि AJAX अनुरोध असीमित है, हम पाइथन में प्रवेश करते हैं जबकि लूप सामग्री को विंडो में जोड़ने के लिए प्रतीक्षा करते हैं। एक बार इसे जोड़ने के बाद, हम विंडो से पुनर्प्राप्त बेस 64 सामग्री को डीकोड करते हैं और इसे फ़ाइल में सहेजते हैं।
यह समाधान सेलेनियम द्वारा समर्थित सभी आधुनिक ब्राउज़रों में काम करना चाहिए, और यह पाठ या बाइनरी, और सभी माइम प्रकारों में काम करता है या नहीं।
वैकल्पिक दृष्टिकोण
जब मैं इस परीक्षण नहीं किया, सेलेनियम आप जब तक एक तत्व डोम में मौजूद है इंतजार करने की क्षमता को वहन करता है। वैश्विक रूप से सुलभ चर तक पॉपअप होने तक लूपिंग करने के बजाय, आप डीओएम में किसी विशेष आईडी के साथ एक तत्व बना सकते हैं और डाउनलोड की गई फ़ाइल को पुनर्प्राप्त करने के लिए ट्रिगर के रूप में उस तत्व के बाध्यकारी का उपयोग कर सकते हैं।
मैं 'urllib' का उपयोग करके पुनः प्राप्त करता हूं और डाउनलोड करने के लिए' urllib.urlretrieve (url) 'का उपयोग करता हूं जहां' url' यूआरएल है जो लिंक भेजता है आप – Serial
नहीं क्योंकि यह केवल क्लिक ईवेंट के साथ काम करता है। – sam
लेकिन यदि आप पृष्ठ के HTML पार्स आप क्लिक करें घटना ब्राउज़र को भेजता है लिंक मिलता है और का उपयोग करें कि – Serial