吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 6126|回复: 27
收起左侧

[Python 转载] 爬取世界各国和地区数据&国旗和国徽的高清图标和图片

  [复制链接]
可控核聚变 发表于 2021-1-1 21:34
本帖最后由 可控核聚变 于 2021-1-1 22:39 编辑

:lol嗨!52的朋友们,大家新年好!我刚来52两个月(算是一个小白,不,是老白)。
我是一个75后的打工人,今年也四十多了,我自己平时在国外做点生意。2020年一月份我从国外回国过年,没想发到突然爆发疫情,更没想到疫情凶猛,迅速蔓延到世界各地,各国的机场口岸关闭,许多航班也停飞了。无奈我出不了国了,只能待在家里每天看看电脑玩玩手机。
三月初的某天在网上刷到一个Python的入门教学视频,我觉得挺有趣的,然后我就网上找各种Python的教学视频和资料自己自学,学到现在也算是刚刚入门了Python。
我对爬虫特别感兴趣,平时也自己写一些爬虫小程序,最近上网时发现一个网站挺好的,这个网站汇总了世界各国和地区的数据,还有高清的国旗、国徽图片和高清国旗立体图标,我就想着写个爬虫把这些都爬下来,也许将来能用的上。
但由于我是半路出家的水平有限,代码写的对不对我也不知道,反正我试了几次能运行,希望各位大神看看有什么不对的地方,大家多多交流。这也算是我在52的第一贴,大家高兴就好,哈哈哈!{:1_893:}

import requests
from lxml import etree
import pandas as pd
import time
import os
import urllib.request

class WorldFlag_Spider(object):
def init(self):
self.start_url = 'http://cn.flagbox.net/'   # 网站根地址
self.headers = {
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36 FS"
}
self.main_folder = r'/Volumes/download/世界各国和地区数据&国旗汇总'  # 主路径
self.content_list = []  # 将包含数据的字典存放到这个列表

# 获取主链接
def data_range(self):
    start_res = requests.get(url=self.start_url, headers=self.headers)
    start_sel = etree.HTML(start_res.content.decode())
    main_url_list = start_sel.xpath('//div[@id="page-bg"]/table/tr/td[2]/ul/li[position()<7]/a/@href')
    main_url = ['http://cn.flagbox.net/' + i for i in main_url_list]
    return main_url

# 获取次链接
def get_url(self, url_1):
    sec_res = requests.get(url=url_1, headers=self.headers)
    sec_sel = etree.HTML(sec_res.content.decode())  
    s_link_list = sec_sel.xpath('//tr/td/a[2]/@href')
    s_link = ['http://cn.flagbox.net/' + s for s in s_link_list]   
    return s_link

# 解析获取到的链接
def paser_url(self, url):
    # print(url)
    response = requests.get(url=url, headers=self.headers)
    if response.status_code == 200:
        selector = etree.HTML(response.content.decode())
        return selector
    else:
        print('请求失败')

# 获取数据
def get_content_list(self, selector):  
    items = {}
    try:
        #  国名
        items['国名'] = selector.xpath('//table[@style="border-collapse: collapse; "]/tr[1]/td[2]/text()')
        items['国名'] = items['国名'][0] if len(items['国名']) > 0 else None

        # 面积
        items['面积'] = selector.xpath('//table[@style="border-collapse: collapse; "]/tr[3]/td[2]/text()')
        items['面积'] = items['面积'][0] if len(items['面积']) > 0 else None

        # 首都
        items['首都'] = selector.xpath('//table[@style="border-collapse: collapse; "]/tr[4]/td[2]/text()')
        items['首都'] = items['首都'][0] if len(items['首都']) > 0 else None

        # 所处位置
        items['所处位置'] = selector.xpath('//table[@style="border-collapse: collapse; "]/tr[5]/td[2]/text()')
        items['所处位置'] = items['所处位置'][0] if len(items['所处位置']) > 0 else None

        # 电话区号
        items['电话区号'] = selector.xpath('//table[@style="border-collapse: collapse; "]/tr[6]/td[2]/text()')
        items['电话区号'] = items['电话区号'][0].replace(' /', '') if len(items['电话区号']) > 0 else None

        # 货币名称
        items['货币名称'] = selector.xpath('//table[@style="border-collapse: collapse; "]/tr[8]/td[2]/text()')
        items['货币名称'] = items['货币名称'][0] if len(items['货币名称']) > 0 else None

        # 语言
        items['语言'] = selector.xpath('//table[@style="border-collapse: collapse; "]/tr[14]/td[2]/text()')
        items['语言'] = items['语言'][0] if len(items['语言']) > 0 else None

        self.content_list.append(items)

        return items['国名']
    except IndexError:
        pass  

# 获取图片链接
def get_imagelink(self, selector):
    # 国旗高清图片
    f_picture = 'http://cn.flagbox.net/' + selector.xpath('//div[@id="page-bg"]/table/tr/td[1]/table/tr/td/ul/li[7]/a/@href')[0]

    # 国旗高清图标
    f_icon = 'http://cn.flagbox.net/' + selector.xpath('//div[@id="page-bg"]/table/tr/td[1]/table/tr/td/p/img[2]/@src')[0]

    # 国徽链接
    emblem = 'http://cn.flagbox.net/' + selector.xpath('//div[@id="page-bg"]/table/tr/td[1]/table/tr/td/p[@align="center"][2]/img/@src')[0]

    return f_picture, f_icon, emblem

# 保存数据
def save_content_list(self, items):
    pf = pd.DataFrame(self.content_list)
    # 指定列的顺序
    order = ['国名','面积','首都','所处位置','电话区号','货币名称','语言']
    pf = pf[order]
    # 打开excel文件 
    file_path = pd.ExcelWriter(self.main_folder + '/' + '世界各国和地区信息汇总.xlsx')  
    # 替换空单元格
    pf.fillna(' ', inplace=True)
    # 输出
    pf.to_excel(file_path, encoding='utf-8', index=False,sheet_name="sheet1")
    file_path.save()
    print('正在保存:{}'.format(items))
    # print(self.content_list)

# 下载图片
def download_image(self, links, item):
    try:
        # 创建子文件夹
        folder = self.main_folder + '/' + item + '/'
        if not os.path.exists(folder):
            os.mkdir(folder)
        for link in links:
            with open(folder + link.split('/')[-2] + os.path.splitext(link)[-1], 'wb') as f:
                image = requests.get(link, headers=self.headers).content
                f.write(image)    

            # 用urllib.request模块进行下载:
            # urllib.request.urlretrieve(link, folder + link.split('/')[-2] + os.path.splitext(link)[-1])
    except:
        print('保存失败')

def run(self):
    # 创建主路径
    if not os.path.exists(self.main_folder):
        os.mkdir(self.main_folder)
    # 1.获取各大洲网页链接
    main_url = self.data_range()
    # 2.遍历各大洲网页链接列表
    for url_1 in main_url:
        # 3.获取各个国家网页链接
        s_link = self.get_url(url_1)
        for url in s_link:
            # 4.解析各个国家网页链接数据
            selector = self.paser_url(url)
            # time.sleep(1)
            # 5.获取各国的各项数值
            item = self.get_content_list(selector)
            # 6.获取各国的国旗图片图标和国徽
            links = self.get_imagelink(selector)
            # 7.保存数据和下载图片
            self.save_content_list(item)
            self.download_image(links, item)

if name == 'main':
WorldFlag = WorldFlag_Spider()  # 实例化对象
WorldFlag.run()




大家运行代码前务必将self.main_folder的主路径改成自己电脑文件夹的路径,因为我用MacOS的,路径结构应该和win电脑的路径结构不一样。

下载图片的时候我尝试使用requests库和urllib.request进行下载,对比之后还是觉得requests更好一点,因为urllib.request不带请求头下载,有时会卡死获取不到数据。不过urllib.request也有优点,一行代码就行了,requests还要写几行上下文。

还有一点,这个网站服务器好像是在国外的,下载图片的时候有点慢,大家耐心点哈!咱也不差这十几分钟的。我也尝试过用threading的多线程爬取,但是总是会获取到很多重复的数据,这个问题我还不知道怎么解决,还在研究中。


2021年我们中国在世界上将是牛气冲天的存在!

将数据保存到Excel文件

将数据保存到Excel文件

将获取到的图片按各个国家的名称分别保存在不同文件夹

将获取到的图片按各个国家的名称分别保存在不同文件夹
flat-res-1280x960.png
rflags_2.png
flat-res-1280x960.png
rflags_2.png
flat-res-1280x960.png
rflags_2.png
emblems.jpg

免费评分

参与人数 5吾爱币 +1 热心值 +4 收起 理由
青蛙考拉 + 1 谢谢@Thanks!
qq9199 + 1 感谢您的宝贵建议,我们会努力争取做得更好!
我是老周 + 1 + 1 我很赞同!
一只小凡凡 -1 违反《中华人民共和国国徽法》的有关规定,已举报!
joneqm + 1 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!

查看全部评分

本帖被以下淘专辑推荐:

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

 楼主| 可控核聚变 发表于 2021-1-2 12:58
青蛙考拉 发表于 2021-1-2 08:54
不分享结果就按违反《国旗国徽法》举报因为我真不会用代码

艾玛!不知道我对国徽做了啥?我好害怕被抓去坐牢,不过分享还是必须的。
链接: https://pan.baidu.com/s/1hP0urLHC03wTyZw4gA0BqQ 提取码: 6tcb

免费评分

参与人数 2吾爱币 +2 热心值 +2 收起 理由
碎了一地的爱 + 1 + 1 谢谢@Thanks!
kingtiger + 1 + 1 谢谢@Thanks!

查看全部评分

vanishDust 发表于 2022-3-25 15:20
可控核聚变 发表于 2021-1-2 12:58
艾玛!不知道我对国徽做了啥?我好害怕被抓去坐牢,不过分享还是必须的。
链接: https://pan.baidu.com/ ...

这个网站不在了,还能再分享下下载的国旗和国徽图片吗
Luckyu920 发表于 2021-1-1 21:49
Monkey0 发表于 2021-1-1 21:52
感谢分享,学习一哈
vista_info 发表于 2021-1-1 22:01
卡死问题可以考虑试试用retry模块
 楼主| 可控核聚变 发表于 2021-1-1 22:10
kai-memory 发表于 2021-1-1 22:01
卡死问题可以考虑试试用retry模块

感谢提醒,又学到东西了
kzwd2020 发表于 2021-1-1 22:20
厉害 这已经不是小白了
jeakoa 发表于 2021-1-1 22:27
学习下爬虫技术
umerl 发表于 2021-1-1 22:29
感谢分享
青蛙考拉 发表于 2021-1-2 08:54
不分享结果就按违反《国旗国徽法》举报因为我真不会用代码
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-22 19:47

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表