#๐ img src error
102 messages ยท Page 1 of 1 (latest)
@wary shadow
Remember to:
- Ask your Python question, not if you can ask or if there's an expert who can help.
- Show a code sample as text (rather than a screenshot) and the error message, if you've got one.
- Explain what you expect to happen and what actually happens.
:warning: Do not pip install anything that isn't related to your question, especially if asked to over DMs.
Please react with โ
to upload your file(s) to our paste bin, which is more accessible for some users.
And with ```py
from http.client import InvalidURL
from pyexpat import features
from colorama import Fore
import requests, os, bs4
url = 'https://xkcd.com/2067/'
os.makedirs('xkcd', exist_ok=True)
while not url.endswith('#') :
print(Fore.BLACK + f'\nDownloading page {url}...')
res = requests.get(url)
res.raise_for_status()
soup = bs4.BeautifulSoup(res.text, "html.parser")
comElem = soup.select('#comic img')
if not comElem:
print(Fore.RED + 'Could not find comic image.')
else:
comUrl = 'https:' + comElem[0].get('src')
print(f'\nDownloading image {comUrl}...')
res.raise_for_status()
imageF = open(os.path.join('xkcd', os.path.basename(comUrl)), 'wb')
for chunk in res.iter_content(10000):
imageF.write(chunk)
imageF.close()
print('Done nga')
exit()```
it prints the text without the hyperlink
How do I stop - res = requests.get(comUrl) being ran if the image is not valid
I want it to skip this image and continue to the next
how do you plan to even know if it's not valid until you have even tried to download it?
because it raises the invalidurl error
as the image uses centre instead of img src
on that page
it raises the exception after you have tried to get it and it fails
you can't know that it will fail before you tried unless you have some other indicator that it wouldnโt be valid
?
Have you ran the code
no, but i don't even understand the problem and what you want to do
This is an image scraper, it fails to run 2067
I want the script to skip over pages that dont have images
Traceback (most recent call last):
File "/Users/m/Documents/Scripts/scrape test.py", line 21, in <module>
res = requests.get(comUrl)
File "/Library/Frameworks/Python.framework/Versions/3.13/lib/python3.13/site-packages/requests/api.py", line 73, in get
return request("get", url, params=params, **kwargs)
File "/Library/Frameworks/Python.framework/Versions/3.13/lib/python3.13/site-packages/requests/api.py", line 59, in request
return session.request(method=method, url=url, **kwargs)
~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Library/Frameworks/Python.framework/Versions/3.13/lib/python3.13/site-packages/requests/sessions.py", line 575, in request
prep = self.prepare_request(req)
File "/Library/Frameworks/Python.framework/Versions/3.13/lib/python3.13/site-packages/requests/sessions.py", line 484, in prepare_request
p.prepare(
~~~~~~~~~^
method=request.method.upper(),
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
...<10 lines>...
hooks=merge_hooks(request.hooks, self.hooks),
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
)
^
File "/Library/Frameworks/Python.framework/Versions/3.13/lib/python3.13/site-packages/requests/models.py", line 367, in prepare
self.prepare_url(url, params)
~~~~~~~~~~~~~~~~^^^^^^^^^^^^^
File "/Library/Frameworks/Python.framework/Versions/3.13/lib/python3.13/site-packages/requests/models.py", line 444, in prepare_url
raise InvalidURL(f"Invalid URL {url!r}: No host supplied")
requests.exceptions.InvalidURL: Invalid URL 'https:/2067/asset/challengers_header.png': No host supplied```
oh, after you gotten the page and searched the html
got it
yes
the url is invalid
https:/2067 is not a correct url
it's this code that is wrong
comUrl = 'https:' + comElem[0].get('src')
yep
its not src
not only that, you are just trying to append https: to whatever url you find there
that's the real problem
nope
the problem is with the js in some of the pages
I have already tried that
changed to http same thing, if u compare 2067 with 2066 you can see the difference if u inspect the image in the middle
just wondering how to continue if its not src
oh, the partial url you got on 2067 was for the image above the main content
yes but the js interferes with it I guess the module bs4 doesnt handle that
this is the one you were trying to get but didn't really construct the correct url for https://xkcd.com/2067/asset/challengers_header.png
correct, bs4 can't handle js by itself
I think my url is fine, if you can suggest a code insert I can try it but I think its the js man
people tend to use something like playwright or selenium for such things
so how can i skip over the js pages thats all i need I plan on learning selenium later
look at the difference between the urls below
https://xkcd.com/2067/asset/challengers_header.png
https:/2067/asset/challengers_header.png
```the first one is the real url and the second one is the one you are trying to get, it's missing the `//xkcd.com` part after `https:`
the problem with the part under that image that is the main content is that it's not just an image that is loaded by js, it's a whole dynamic
yep
yes, i know
how can I skip over it
you can catch the exception and move on
the scraper pulls them automatically, it has it like that by default
i have tried that I dont know where to nest it
the code you posted isn't the same as the one that produced this error
or it's just incomplete
this line is missing from the code you posted
res = requests.get(comUrl)
```and is the one the throws that error form line 21 in your file named `/Users/m/Documents/Scripts/scrape test.py`
here ```py
from pyexpat import features
from colorama import Fore
import requests, os, bs4
url = 'https://xkcd.com/2067/'
os.makedirs('xkcd', exist_ok=True)
while not url.endswith('#') :
print(Fore.BLACK + f'\nDownloading page {url}...')
res = requests.get(url)
res.raise_for_status()
soup = bs4.BeautifulSoup(res.text, "html.parser")
comElem = soup.select('#comic img')
if not comElem:
print(Fore.RED + 'Could not find comic image.')
else:
comUrl = 'https:' + comElem[0].get('src')
print(f'\nDownloading image {comUrl}...')
res = requests.get(comUrl)
res.raise_for_status()
imageF = open(os.path.join('xkcd', os.path.basename(comUrl)), 'wb')
for chunk in res.iter_content(10000):
imageF.write(chunk)
imageF.close()
print('Done nga')
exit()```
there it is, it's much easier if it's the right code that we are looking at
instead of
res = requests.get(comUrl)
```you want
```py
try:
res = requests.get(comUrl)
except requests.exceptions.InvalidURL:
print("Skipping invalid URL: {comUrl}")
continue
```or you can use `break` if you want to end the loop instead of `continue`
continue runs the next iteration of the loop
so it depends on what you want to do
this doesnt work
oh, sorry, copied the wrong line
you meant - res = requests.get(comUrl)
there, yeah
actually worked thanks a lot bro
the text moved up while i was copying it and i didn't check
yh, it works but it prints out the print("skipping etc") on every line - i had this issue before with except
like it stays on 2067
as i said, the url you construct is not correct
so I can't even skip it?
I have to amend this - comUrl = 'https:' + comElem[0].get('src') ?
this line
comUrl = 'https:' + comElem[0].get('src')
```needs to be
```py
comUrl = 'https://xkcd.com' + comElem[0].get('src')
I see
your script will download this image https://xkcd.com/2067/asset/challengers_header.png
actually works
which is part of the comic for this page, but the main part isn't an image and you can't just download it in the same way
yeah, i told you the url you were building was wrong
With selenium I would be able to grab the js image?
i'm not so sure as it's so much more then just an image
I know
But the image can be downloaded by itself, js was used for the zooming im feature
but there are js games that wouldnt work
no, it's not an image, it's a json file with coordinates that gets rendered on a html5 canvas on the page, here is the json file used for the data of the map https://xkcd.com/2067/asset/map-data.json
it just looks like it, it's what the browser has rendered on the canvas that you are saving
if you zoom in on a little part at one side and then save it again you'll only get that as an image
this is because it's just the rendered canvas that you are saving as an image
it's the javascript and the browser that is doing all the heavy lifting to create that image in your browser
no problem
what did u use to learn s a begineer? not just python. Just curious
books ๐
not the ones i read back then, i tried to start at age 8 but i couldn't find any good books in my native language, so i hade to wait until i could read at least a bit of english at age 10 when i started to program
I see
one free online book that is quite good is https://automatetheboringstuff.com/
A Page in : Automate the Boring Stuff with Python
!close
This help channel has been closed. Feel free to create a new post in #1035199133436354600. To maximize your chances of getting a response, check out this guide on asking good questions.