Downloading Images - Unable to find correct selector - Printable Version +- Python Forum (https://python-forum.io) +-- Forum: Python Coding (https://python-forum.io/forum-7.html) +--- Forum: Web Scraping & Web Development (https://python-forum.io/forum-13.html) +--- Thread: Downloading Images - Unable to find correct selector (/thread-23844.html) |
Downloading Images - Unable to find correct selector - Brompy - Jan-20-2020 I'm trying to write a script that 1) goes to a website 2) downloads and parses the HTML 3) downloads a comic image 4) selects the "previous comic button" 5) repeats 1-4 The script is failing on either hitting the "previous comic" button, or downloading the next page before it can reach the second image. I have tried tinkering with the different selectors, but I'm not sure why it's not working. #! python3 #swordscraper.py - Downloads all the swords comics. import requests, os, bs4 os.chdir(r'C:\Users\bromp\OneDrive\Desktop\Python') os.makedirs('swords', exist_ok=True) #store comics in /swords url = 'https://swordscomic.com/' #starting url while not url.endswith('#'): #Download the page. print('Downloading page %s...' % url) res = requests.get(url) res.raise_for_status soup = bs4.BeautifulSoup(res.text, 'html.parser') #Find the URL of the comic image. comicElem = soup.select('#comic-image') if comicElem == []: print('Could not find comic image.') else: comicUrl = comicElem[0].get('src') comicUrl = "http://" + comicUrl if 'swords' not in comicUrl: comicUrl=comicUrl[:7]+'swordscomic.com/'+comicUrl[7:] #Download the image. print('Downloading image %s...' % (comicUrl)) res = requests.get(comicUrl) res.raise_for_status() #Save the image to ./swords imageFile = open(os.path.join('swords', os.path.basename(comicUrl)), 'wb') for chunk in res.iter_content(100000): imageFile.write(chunk) imageFile.close() #Get the Prev button's url. prevLink = soup.select('a[id="navigation-previous"]')[1] url = 'https://swordscomic.com/' + prevLink.get('href')This is the output it gives when I run it: Downloading page https://swordscomic.com/... Downloading image http://swordscomic.com//media/Swords364t.png... Traceback (most recent call last): File "C:\Users\bromp\AppData\Local\Programs\Python\Python37-32\swordscraper.py", line 40, in <module> prevLink = soup.select('a[id="navigation-previous"]')[1] IndexError: list index out of rangeDo I need to use a different module, like Selenium? RE: Downloading Images - Unable to find correct selector - Larz60+ - Jan-20-2020 I think you want to use selenium for this. How-to do this: web scraping part 1 web scraping part 2 RE: Downloading Images - Unable to find correct selector - snippsat - Jan-20-2020 Can use Selenium,but it's a cooler way here as they use Roman numerals in url. Then can write it so can use integer to navigate or eg download all images. Example to get one image. # roman.py import requests import os, re from roman_convert import roman_to_int, int_to_roman def make_url(roman_number): return f'https://swordscomic.com/comic/{roman_number}/' def download(url, img_nr): img = requests.get(url) img_name = f'{int_to_roman(img_nr)}.png' with open(img_name, 'wb') as f_out: f_out.write(img.content) if __name__ == '__main__': img_nr = 361 url = f'https://swordscomic.com/media/Swords{img_nr}t.png' roman_number = int_to_roman(img_nr) org_link = make_url(roman_number) print(f'Dowloading --> {org_link}') download(url, img_nr)
CCCLXI.png [Image: I58IDh.png] roman_convert that i import is not written bye me,just code from first hit on Google.RE: Downloading Images - Unable to find correct selector - Brompy - Jan-22-2020 Thank you both for the replies. Snippsat, your solution is very cool/clever. But when I try to use it does download a .png, but it is an unreadable .png file that is only 13kb large. What is going wrong? RE: Downloading Images - Unable to find correct selector - snippsat - Jan-22-2020 (Jan-22-2020, 11:32 AM)Brompy Wrote: But when I try to use it does download a .png, but it is an unreadable .png file that is only 13kb large. What is going wrong?Not all days have images,so it will be 13kb on these days. Setup is: E:\div_code\home\ |-- roman.py |-- roman_convertIf i change roman.py to download more images at once.Also make it so it show days with no image in both int and roman numb. So here download 25 days,4 days has no image as show in list under. [('CCCXLVI.png', 346), ('CCCXLVII.png', 347), ('CCCLVI.png', 356), ('CCCLXIII.png', 363)] # roman.py import requests import os, re from roman_convert import roman_to_int, int_to_roman def make_url(roman_number): return f'https://swordscomic.com/comic/{roman_number}/' no_image = [] def download(url, img_nr): img = requests.get(url) img_name = f'{int_to_roman(img_nr)}.png' with open(img_name, 'wb') as f_out: if len(img.content) < 15000: no_image.append(img_name) else: f_out.write(img.content) if __name__ == '__main__': #img_nr = 364 for img_nr in range(340, 365): url = f'https://swordscomic.com/media/Swords{img_nr}t.png' roman_number = int_to_roman(img_nr) org_link = make_url(roman_number) print(f'Dowloading --> {org_link}') download(url, img_nr) day_int = [roman_to_int(ro.split('.')[0]) for ro in no_image] print(list(zip(no_image, day_int)))Run:
Can show a quick test with Selenium,as this is maybe not so easy if new to this. Here i go back 3 times,then send site source code to BS,so can to find the real download(it's not the roman numerals link) link in meta tag. To download i use same function with some modifications. from selenium import webdriver from selenium.webdriver.chrome.options import Options from selenium.webdriver.common.keys import Keys from bs4 import BeautifulSoup import time, os import requests def download(img_url): img = requests.get(img_url) img_name = os.path.basename(img_url) with open(img_name, 'wb') as f_out: if len(img.content) < 15000: no_image.append(img_name) else: f_out.write(img.content) if __name__ == '__main__': #--| Setup chrome_options = Options() #chrome_options.add_argument("--headless") browser = webdriver.Chrome(executable_path=r'C:\cmder\bin\chromedriver.exe') #--| Parse or automation browser.get('https://swordscomic.com/comic/CCCLXV/') back = browser.find_elements_by_css_selector('#navigation-previous')[0].click() time.sleep(3) back = browser.find_elements_by_css_selector('#navigation-previous')[0].click() time.sleep(3) back = browser.find_elements_by_css_selector('#navigation-previous')[0].click() # Give source code to BeautifulSoup soup = BeautifulSoup(browser.page_source, 'html.parser') img_url = soup.find('meta', property="og:image") img_url = img_url.attrs['content'] download(img_url) browser.quit() |