从零开始写Python爬虫 --- 1.8 爬虫实践: 电影排行榜和图片批量下载

从零开始写Python爬虫 --- 1.8 爬虫实践: 电影排行榜和图片批量下载

这次我们要写的是爬取热门电影排行榜,依旧十分的简单,目的在于再次巩固已经学到的知识。由于用的还是前面几章用到的老套路,文章里我就不过多的赘述了。

目标分析:

这次要爬的网站是:

http://dianying.2345.com/top/


需要的找到的信息十分简单,电影的名字,主演,简介,和标题图


网站结构分析:

先来简单看一下网站的结构:


可以看到,我们需要的主题部分,都被包裹在‘<ul>“列表标签里,

那么我们简单的用bs4库找到 "<ul>" tag并迭代取出每一条“<li>”tag,

最后再从没个<li>标签里找到我们需要的信息就行。


遇到的问题?

这次的代码十分的简单,但是我在实现的过程中遇到了一些小问题:

编码编码编码,还是编码

我一开始在抓取网页文本的时候,依旧的采用的是:

r.encoding=r.apparent_encoding 

本来以为会万无一失,没想到抓取下来的文本居有部分乱码。


比如这个叫 辰颉詮 的演员
爬取下来居然是:


于是我稍微调试了一下:

print (r.encoding)
# gbk
print (r.apparent_encdoing)
# GB2312

原来问题出在这这里,requests库从GET下来的body中分析了一下编码,

得出的结论是 :GB2312 。

而这个编码实际上和网站的编码是不同的,

所以才会得到个别的乱码。

解决方式也很简答,手动将编码设置成GBK就解决了。

那么GBK GB2312之间到底有什么区别呢?
以下内容来自wiki百科:


GBK:

汉字内码扩展规范,称GBK,全名为《汉字内码扩展规范(GBK)》1.0版,由中华人民共和国全国信息技术标准化技术委员会1995年12月1日制订,国家技术监督局标准化司和电子工业部科技与质量监督司1995年12月15日联合以《技术标函[1995]229号》文件的形式公布。 GBK共收录21886个汉字和图形符号,其中汉字(包括部首和构件)21003个,图形符号883个。
GBK的K为汉语拼音Kuo Zhan(扩展)中“扩”字的声母。英文全称Chinese Internal Code Extension Specification。

GB2312

GB 2312 或 GB 2312–80 是中华人民共和国国家标准简体中文字符集,全称《信息交换用汉字编码字符集·基本集》,又称GB0,由中国国家标准总局发布,1981年5月1日实施。GB 2312编码通行于中国大陆;新加坡等地也采用此编码。中国大陆几乎所有的中文系统和国际化的软件都支持GB 2312

既然都说到这里了,也来介绍一下UTF-8

UTF-8(8-bit Unicode Transformation Format)是一种针对Unicode的可变长度字符编码,也是一种前缀码。它可以用来表示Unicode标准中的任何字符,且其编码中的第一个字节仍与ASCII兼容,这使得原来处理ASCII字符的软件无须或只须做少部分修改,即可继续使用。因此,它逐渐成为电子邮件、网页及其他存储或发送文字的应用中,优先采用的编码。

我们可以得知,GBK和GB2312 都是中文体系下的编码方式,按

道理来说,不会出现问题,那为什么那位演员的名字没有显示出来呢?

其实很简单啊,GBK比GB2312后推行,自然也就支持更多汉字的显示,

例如那位演员名字中的生僻字 “颉詮”

当然,我的个人偏好依旧是是UTF-8 他对中文有着及其强大的支持,怎么说呢,希望Unicode能早点统一整个web编码吧!
还有各家系统的换行符 也是一个坑。

Mac : “\n”
Win : "\n\r"
Linxu: "\r"或者"\n"

总之就是异常的难受,这当中当然有很多历史和商业原因,

想了解的小伙伴可以自己去查查看~


图片下载:

在电影排行榜爬虫当中,我们有一项目标是:‘爬取每个电影的标题图’,

有人肯定就觉得很难实现,因为图片又不是字符,如何以文本的形式爬下来呢?

其实,这里有一个误区,在计算机的世界里,一切的数据归根到底都是以“0”和“1”的二进制形式存在的。

图片自然也不例外,任何一张图片,都是以“字节流 ”的形式,

通过了一定的编码方式,被计算机排列组合,从而显示成我们肉眼所看到的图片。

那么我们只要把图片数据从网上下载下来,然后再以二进制的格式写入到本地就可以啦。

给出一个图片下载的通用代码片段:

    import requests
    
    def get_pic_from_url(url):
        #从url以二进制的格式下载图片数据
        pic_content = requests.get(url,stream=True).content
        open('filename','wb').write(pic_content)

是不是很简答呢? 当然,你们也可以在这个基础上进行添加和完善。

代码的书写:

由于这次的代码比较简单。并且也没有太多的新的东西,我就不一一解释了,直接贴上代码。另外,代码里有详细的注释:

'''
爬取最新电影排行榜单
url:http://dianying.2345.com/top/
使用 requests --- bs4 线路
Python版本: 3.6
OS: mac os 12.12.4
'''

import requests
import bs4


def get_html(url):
    try:
        r = requests.get(url, timeout=30)
        r.raise_for_status
        # 该网站采用gbk编码!
        r.encoding = 'gbk'
        return r.text
    except:
        return "someting wrong"


def get_content(url):
    html = get_html(url)
    soup = bs4.BeautifulSoup(html, 'lxml')
    
    # 找到电影排行榜的ul列表
    movies_list = soup.find('ul', class_='picList clearfix')
    movies = movies_list.find_all('li')
    
    for top in movies:
        #找到图片连接,
        img_url=top.find('img')['src']
        

        name = top.find('span',class_='sTit').a.text
        #这里做一个异常捕获,防止没有上映时间的出现
        try:
            time = top.find('span',class_='sIntro').text
        except:
            time = "暂无上映时间"
        
        #这里用bs4库迭代找出“pACtor”的所有子孙节点,即每一位演员解决了名字分割的问题
        actors = top.find('p',class_='pActor')
        actor= ''
        for act in actors.contents:
            actor = actor + act.string +'  '
        #找到影片简介
        intro = top.find('p',class_='pTxt pIntroShow').text

        print("片名:{}\t{}\n{}\n{} \n \n ".format(name,time,actor,intro) )
        
        #我们来吧图片下载下来:
        with open('/Users/ehco/Desktop/img/'+name+'.png','wb+') as f:
            f.write(requests.get(img_url).content)


def main():
    url = 'http://dianying.2345.com/top/'
    get_content(url)

if __name__ == "__main__":
    main()

结果展示:

电影信息输出:


图片下载:


好了,本次的小例子到这里就结束了,其实学到这里,bs4库的基本用法我们也掌握了,爬虫的基本思路相信大家心里也都有个数,那么我们接下来是不是要学更加高级的技术了呢?别急,慢慢来,先自己动手多写几个小demo。相信你会有更大的收获!

最近学校里在本科教学评估,也不能翘课在家写代码,到了学期末一堆论文等着我,再次感叹一下文科生伤不起!调个论文格式我都要上天了!?


每天的学习记录都会 同步更新到:
微信公众号: findyourownway

知乎专栏:从零开始写Python爬虫 - 知乎专栏

blog : www.ehcoblog.ml

Github: Ehco1996/Python-crawler

编辑于 2017-05-08

文章被以下专栏收录