国家地理每日精选爬取

在刷Jellow的时候看见一个人说第一次付费应用,因为国家地理每日精选里的图片太好看,我就好奇有多好看吗?

20203291-3415208

恰逢前几天爬虫爬了必应每日一图成就感满满,今日就准备那这个国家地理再次试试手。

过程

首先就在网上找国家地理每日家精选的web端, http://dili.bdatu.com/index.php/Share/adindex/id/208 ,只发现了这个,通过改变id发现有些id好像还没有内容,但是不会报错,刚开始我以为是特定的数字段id才有内容的,然后就没有太在意这个。这样考虑的话我就遇到了一个问题,我手动测试ID发现202有内容,203,204……都是有的,于是我就挑了一段测试一下都是有的,于是我大胆的猜测他在202-1000这个字段都是有内容的,直接写代码爬取。于是问题就来了,202-206都是可以的,207就报错了,然后202-206的内容也没有保存下来。

20203292-3887965

Traceback (most recent call last):
  File "e:/Python/webpapapa/NAGE.py", line 11, in 
    src = items[1].get('src')
IndexError: list index out of range

这个时候我才明白我在b站看视频的时候老师一直强调了一个try、except在爬虫中的重要性,于是我就去加上这个代码,一开始我以为是requests.get出错了,于是我加上了

try:
    return r.content
except ConnectionError:
    print('连接失败')

但是还是会出错,进一步研究发现,这个网页get的没有问题,问题在于获取img标签的src的值

items = soup.find_all("img")
src = items[i].get('src')

我们在美丽汤里熬成的汤中没有img标签所以items获取的字典就为空,这个时候get(‘src’)就会报错,发现了问题所在,就很好解决了,后面就顺利爬取了一些图片。

20203293-2463972

这次似乎挺成功的,但是由于我一口气设置了202-1000这么多个连接,于是爬到第983页的时候出现了一个问题,一个没有预想到的问题。

Traceback (most recent call last):
  File "C:Users吾AppDataLocalProgramsPythonPython37libsite-packagesrequestsmodels.py", line 750, in generate
    for chunk in self.raw.stream(chunk_size, decode_content=True):
  File "C:Users吾AppDataLocalProgramsPythonPython37libsite-packagesurllib3response.py", line 494, in stream
    data = self.read(amt=amt, decode_content=decode_content)
  File "C:Users吾AppDataLocalProgramsPythonPython37libsite-packagesurllib3response.py", line 459, in read
    raise IncompleteRead(self._fp_bytes_read, self.length_remaining)
  File "C:Users吾AppDataLocalProgramsPythonPython37libcontextlib.py", line 130, in __exit__
    self.gen.throw(type, value, traceback)
    raise ProtocolError('Connection broken: %r' % e, e)
urllib3.exceptions.ProtocolError: ("Connection broken: ConnectionResetError(10054, '远程主机强迫关闭了一个现有的连接。', None, 10054, None)", ConnectionResetError(10054, '远程主机强迫关闭了一个现有的连接。', None, 10054, None))

百度了一下发现是因为使用urlopen方法太过频繁,引起远程主机的怀疑,被网站认定为是攻击行为。导致urlopen()后,request.read()一直卡死在那里。最后抛出10054异常。 解决方法是要time.sleep(t),每次访问后休息一会再爬,让这个行为更像人一点。

有一点点明白了,但是我并没有解决他,任由它去了,以后写爬虫的时候注意一下就好。

这次爬虫总共爬取了740张,也不知道质量如何,只是去练习爬虫。

可在我的网盘中获取所有图片:http://pan.wubuster.com/?/national_geographic.zip

20203294-2392893

代码

import requests
from bs4 import BeautifulSoup
import os

def get_html(url):
    headers = {'User-agent': 'Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 UBrowser/6.2.3964.2 Safari/537.36'}
    r = requests.get(url, headers=headers)
    try:
        return r.content
    except ConnectionError:
        print('连接失败')
    

def download(text):
    headers = {'User-agent': 'Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 UBrowser/6.2.3964.2 Safari/537.36'}
    soup = BeautifulSoup(text, 'html.parser')
    items = soup.find_all("img")
    for i in range(1,11):
        if i:
            try:
                src = items[i].get('src')
                img = requests.get(src,headers=headers)
                root = "E://national_geographic//"
                if os.path.exists(root) == False:
                    os.makedirs(root)
                path = root + src.split('/')[-1]
                with open(path, 'wb') as f: #wb是以二进制写入
                    f.write(img.content) #r.content就是二进制查看
                    f.close()
            except:
                print("src获取失败")        
def main():
    for i in range(202,1000):
        url = 'http://dili.bdatu.com/index.php/Share/adindex/id/{}'.format(i)
        text = get_html(url)
        download(text)
        print("第{}页下载完成".format(i))

if __name__ == "__main__":
    main()