私は学習していますPython Automate the Boring Stuff。このプログラムは http://xkcd.com/ に行き、すべての画像をオフラインでダウンロードすることになっています。表示しています。
バージョン2.7およびMacを使用しています。
何らかの理由で、「スキーマが指定されていません」などのエラーと、request.get()自体の使用に関するエラーが発生しています。
ここに私のコードがあります:
# Saves the XKCD comic page for offline read
import requests, os, bs4, shutil
url = 'http://xkcd.com/'
if os.path.isdir('xkcd') == True: # If xkcd folder already exists
shutil.rmtree('xkcd') # delete it
else: # otherwise
os.makedirs('xkcd') # Creates xkcd foulder.
while not url.endswith('#'): # If there are no more posts, it url will endswith #, exist while loop
# Download the page
print 'Downloading %s page...' % url
res = requests.get(url) # Get the page
res.raise_for_status() # Check for errors
soup = bs4.BeautifulSoup(res.text) # Dowload the page
# Find the URL of the comic image
comicElem = soup.select('#comic img') # Any #comic img it finds will be saved as a list in comicElem
if comicElem == []: # if the list is empty
print 'Couldn\'t find the image!'
else:
comicUrl = comicElem[0].get('src') # Get the first index in comicElem (the image) and save to
# comicUrl
# Download the image
print 'Downloading the %s image...' % (comicUrl)
res = requests.get(comicUrl) # Get the image. Getting something will always use requests.get()
res.raise_for_status() # Check for errors
# Save image to ./xkcd
imageFile = open(os.path.join('xkcd', os.path.basename(comicUrl)), 'wb')
for chunk in res.iter_content(10000):
imageFile.write(chunk)
imageFile.close()
# Get the Prev btn's URL
prevLink = soup.select('a[rel="prev"]')[0]
# The Previous button is first <a rel="prev" href="/1535/" accesskey="p">< Prev</a>
url = 'http://xkcd.com/' + prevLink.get('href')
# adds /1535/ to http://xkcd.com/
print 'Done!'
エラーは次のとおりです。
Traceback (most recent call last):
File "/Users/XKCD.py", line 30, in <module>
res = requests.get(comicUrl) # Get the image. Getting something will always use requests.get()
File "/Library/Python/2.7/site-packages/requests/api.py", line 69, in get
return request('get', url, params=params, **kwargs)
File "/Library/Python/2.7/site-packages/requests/api.py", line 50, in request
response = session.request(method=method, url=url, **kwargs)
File "/Library/Python/2.7/site-packages/requests/sessions.py", line 451, in request
prep = self.prepare_request(req)
File "/Library/Python/2.7/site-packages/requests/sessions.py", line 382, in prepare_request
hooks=merge_hooks(request.hooks, self.hooks),
File "/Library/Python/2.7/site-packages/requests/models.py", line 304, in prepare
self.prepare_url(url, params)
File "/Library/Python/2.7/site-packages/requests/models.py", line 362, in prepare_url
to_native_string(url, 'utf8')))
requests.exceptions.MissingSchema: Invalid URL '//imgs.xkcd.com/comics/the_martian.png': No schema supplied. Perhaps you meant http:////imgs.xkcd.com/comics/the_martian.png?
問題は、プログラムに関する本のセクションを何度も読み、Requests docを読み、他の質問をここで見ていることです。私の構文は正しく見えます。
ご協力いただきありがとうございます!
編集:
これは機能しませんでした:
comicUrl = ("http:"+comicElem[0].get('src'))
Http:を追加する前に、スキーマが提供されていないエラーを取り除くと思いました。
comicUrl
をこれに変更します
comicUrl = comicElem[0].get('src').strip("http://")
comicUrl="http://"+comicUrl
if 'xkcd' not in comicUrl:
comicUrl=comicUrl[:7]+'xkcd.com/'+comicUrl[7:]
print "comic url",comicUrl
スキーマがないということは、http://
またはhttps://
を提供していないことを意味し、トリックを実行します。
編集:このURL文字列を見てください!:
URL '//imgs.xkcd.com/comics/the_martian.png':
説明:
いくつかのXKCDページには、単純な画像ファイルではない特別なコンテンツがあります。それはいいです;あなたはそれらをスキップすることができます。セレクタが要素を見つけられない場合、soup.select( '#comic img')は空のリストを返します。
作業コード:
import requests,os,bs4,shutil
url='http://xkcd.com'
#making new folder
if os.path.isdir('xkcd') == True:
shutil.rmtree('xkcd')
else:
os.makedirs('xkcd')
#scrapiing information
while not url.endswith('#'):
print('Downloading Page %s.....' %(url))
res = requests.get(url) #getting page
res.raise_for_status()
soup = bs4.BeautifulSoup(res.text)
comicElem = soup.select('#comic img') #getting img tag under comic divison
if comicElem == []: #if not found print error
print('could not find comic image')
else:
try:
comicUrl = 'http:' + comicElem[0].get('src') #getting comic url and then downloading its image
print('Downloading image %s.....' %(comicUrl))
res = requests.get(comicUrl)
res.raise_for_status()
except requests.exceptions.MissingSchema:
#skip if not a normal image file
prev = soup.select('a[rel="prev"]')[0]
url = 'http://xkcd.com' + prev.get('href')
continue
imageFile = open(os.path.join('xkcd',os.path.basename(comicUrl)),'wb') #write downloaded image to hard disk
for chunk in res.iter_content(10000):
imageFile.write(chunk)
imageFile.close()
#get previous link and update url
prev = soup.select('a[rel="prev"]')[0]
url = "http://xkcd.com" + prev.get('href')
print('Done...')
私はちょうどこの同じエラーがあり、上記の@Ajay推奨の回答を使用したことをここでチャイムしたいのですが、まだ問題が発生していることを追加した後でも、プログラムが最初の画像をダウンロードした直後に停止してこのエラーを返します:
ValueError: Unsupported or invalid CSS selector: "a[rel"
これは、プログラムの最後の行の1つを指し、「Prevボタン」を使用して次の画像に移動してダウンロードします。
とにかくbs4のドキュメントを読んだ後、次のようにわずかな変更を加えましたが、今ではうまく動作しているようです:
prevLink = soup.select('a[rel^="prev"]')[0]
他の誰かが同じ問題に遭遇するかもしれないので、このコメントを追加すると思いました。