快速收集信息,Python爬虫教你一招爬取豆瓣Top250信息!

随着科技不断发展,互联网已经进入了大数据时代。

我们过去只能通过报刊杂志、电视广播获取到有限的信息,而现在,互联网上的海量数据,让我们享受到了信息自由。

但是,我们获取到了海量的信息同时,也带来了大量的垃圾信息。

所以必须要通过一些技术手段进行收集、整理、分析、筛选,然后才能获取到对我们有用的相关内容。
而这个技术手段,就叫网络爬虫技术。

前两天老铁跟我吐槽,他的老板突然要他收集豆瓣电影Top250榜单上的电影详细信息,然后做成Excel表格。

他当时听到这个消息很崩溃,他的本职工作不是这一方面,只是被临时拉来顶班。他当时跟我说这么多的信息,复制粘贴也需要很多时间,在他花费了一大把时间,但是并没有什么成果。

所以他来问我:你们程序员有没有什么黑科技,可以快速收集网页信息。

我当时灵光一闪,这用Python爬虫技术不就可以很快实现。用几行代码快速获取信息,生成Excel表格。

image

爬虫案例讲解

爬虫可以爬取的内容有很多,比如房价、房源数据,股票信息或者是购物网上的一些商品信息,就是大部分网页上有的信息都可以爬取下来,尤其对于信息收集工作者来说,简直是福音。

对于初学者来说,复杂的爬虫案例可能会有困难,所以我教大家简单的网页信息爬取,以豆瓣电影TOP250榜单为例,把电影信息爬取下来。话不多说,往下看↓ ↓ ↓

这是爬取的结果:


image

我这边用的是pychram 运行的,最开始就是导入库和模块

# -*- codeing = utf-8 -*-

from bs4 import BeautifulSoup  # 网页解析,获取数据

import re  # 正则表达式,进行文字匹配

import urllib.request, urllib.error  # 指定URL,获取网页数据

import xlwt  # 进行excel操作

#import sqlite3  # 进行SQLite数据库操作

开头的这个是设置编码为utf-8 ,写在开头,防止乱码。

本次爬虫能用到的就是这些库,后面也都加了注释,我这里主要讲存储在Excel里,也可以用数据库操作。

我们主要爬取的是
https://movie.douban.com/top250 这个网址,它跳转的是以这个网页,我们主要是要爬取左侧电影的信息。

image

爬取网页大致分三步

1.获取数据

2.解析内容

3.保存数据

image

(一)获取数据

def main():
    baseurl = "https://movie.douban.com/top250?start="  #要爬取的网页链接
    # 1.爬取网页
    datalist = getData(baseurl)

baseurl 就是我们要爬取的网页链接,下面就是调用getData(baseurl)

# 爬取网页
def getData(baseurl):
    datalist = []  #用来存储爬取的网页信息
    for i in range(0, 10):  # 调用获取页面信息的函数,10次
        url = baseurl + str(i * 25)
        html = askURL(url)
        

这里为什么要调用10次?因为豆瓣电影Top250,页面包括250条电影数据,分10页,每页25条。每页URL的不同之处:最后的页面数值=(页面数-1)25,所以我们需要访问页面10次,2510=250。

然后就请求网页,Python一般用urllib2库获取页面

# 得到指定一个URL的网页内容
def askURL(url):
    head = {  # 模拟浏览器头部信息,向豆瓣服务器发送消息
        "User-Agent": "Mozilla / 5.0(Windows NT 10.0; Win64; x64) AppleWebKit / 537.36(KHTML, like Gecko) Chrome / 80.0.3987.122  Safari / 537.36"
    }
    # 用户代理,表示告诉豆瓣服务器,我们是什么类型的机器、浏览器(本质上是告诉浏览器,我们可以接收什么水平的文件内容)

    request = urllib.request.Request(url, headers=head)
    html = ""
    try:
        response = urllib.request.urlopen(request)
        html = response.read().decode("utf-8")
    except urllib.error.URLError as e:
        if hasattr(e, "code"):
            print(e.code)
        if hasattr(e, "reason"):
            print(e.reason)
    return html
  • 对每一个页面,调用askURL函数获取页面内容。

  • 定义一个获取页面的函数askURL, 传入一个urI参数,表示网址,如https:/ /movie.douban.com/ top250?start=0。

  • urllib2.Request生成请求;;urllib2.urlopen发送请求获取响应; read 获取页面内容。

  • 在访问页面时经常会出现错误,为了程序正常运行,加入异常捕获try...except...语句。不然可能会出现这样的错误代码↓

418 I’m a teapotThe HTTP 418 I’m a teapot client error response code indicates that
the server refuses to brew coffee because it is a teapot. This error
is a reference to Hyper Text Coffee Pot Control Protocol which was an
April Fools’ joke in 1998.

翻译为:HTTP 418 I‘m a teapot客户端错误响应代码表示服务器拒绝煮咖啡,因为它是一个茶壶。这个错误是对1998年愚人节玩笑的超文本咖啡壶控制协议的引用。

其实就是被网站认出来是爬虫,所以需要掩饰一下



(二)解析内容

接下来就是逐一解释数据

# 2.逐一解析数据
        soup = BeautifulSoup(html, "html.parser")
        for item in soup.find_all('div', class_="item"):  # 查找符合要求的字符串
            data = []  # 保存一部电影所有信息
            item = str(item)
            link = re.findall(findLink, item)[0]  # 通过正则表达式查找

主要是通正则表达式查找。

正则表达式

正则表达式,通常被用来检索、替换那些符合某个模式(规则)的文本。

正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一-些特定字符及这些特定字符的组合,组成一个"规则字符串”, 这个"规则字符串”用来表达对字符串的一种过滤逻辑。Python中使用re模块操作正则表达式。

#影片详情连接的规则
findLink = re.compile(r'<a href="(.*?)">')  # 创建正则表达式对象,影片详情链接的规则

#影片图片
findImgSrc = re.compile(r'<img.*src="(.*?)"', re.S) #re.S 让换行符包含在字符中

#影片片名
findTitle = re.compile(r'<span class="title">(.*)</span>')

#影片评分
findRating = re.compile(r'<span class="rating_num" property="v:average">(.*)</span>')

#评价人数
findJudge = re.compile(r'<span>(\d*)人评价</span>')

#一句话简介
findInq = re.compile(r'<span class="inq">(.*)</span>')

#影片相关内容
findBd = re.compile(r'<p class="">(.*?)</p>', re.S)

然后应用规则找到我们所需要的内容

 #影片详情连接
            link = re.findall(findLink, item)[0]       # re库用来通过正则表达式查找指定的字符串
            data.append(link)                          #添加链接

            imgSrc = re.findall(findImgSrc, item)[0]
            data.append(imgSrc)                        #添加图片

            titles = re.findall(findTitle, item)       #片名可能只有中文名没有外文名
            if (len(titles) == 2):
                ctitle = titles[0]                     #添加中文名
                data.append(ctitle)
                otitle = titles[1].replace("/", "")    #去掉无关字符
                data.append(otitle)                    #添加外文名
            else:
                data.append(titles[0])
                data.append(' ')                       #如果没有外文名就留空

            rating = re.findall(findRating, item)[0]
            data.append(rating)                        #添加评分

            judgeNum = re.findall(findJudge, item)[0]
            data.append(judgeNum)                      #添加评分人数

            inq = re.findall(findInq, item)
            if len(inq) != 0:
                inq = inq[0].replace("。", "")         #去掉句号
                data.append(inq)                       #添加一句话简介
            else:
                data.append(" ")

            bd = re.findall(findBd, item)[0]          #电影详细信息
            bd = re.sub('<br(\s+)?/>(\s+)?', "", bd)  #去掉<br/>
            # bd = re.sub('/', "", bd)
            data.append(bd.strip())                   #去掉空格

            datalist.append(data)                     #把处理好的电影信息放入datalist

    return datalist

(三)保存数据

最后就是将获取到的内容保存到Excel里面

# 保存数据到表格
def saveData(datalist,savepath):
    print("save.......")
    book = xlwt.Workbook(encoding="utf-8",style_compression=0) #创建workbook对象
    sheet = book.add_sheet('豆瓣电影Top250', cell_overwrite_ok=True) #创建工作表
    col = ("电影详情链接","海报图片链接","影片中文名","影片外文名","豆瓣评分","评价人数","一句话简介","详细信息")
    for i in range(0,8):
        sheet.write(0,i,col[i])  #列名
    for i in range(0,250):
        # print("第%d条" %(i+1))       #输出语句,用来测试
        data = datalist[i]
        for j in range(0,8):
            sheet.write(i+1,j,data[j])  #数据
    book.save(savepath) #保存

最后运行之后在左侧会出现一个这样的文件:

打开可以看到就是我们获取到的结果:

1623918331187.gif

得到我们想要的结果后,稍微调整以下就可以交给领导了,详细又清晰。我教给老铁这种方法后(从来没有接触过代码的老铁都学会了),他都开心疯了~


最后附上我所有的源代码

# -*- codeing = utf-8 -*-
from bs4 import BeautifulSoup  # 网页解析,获取数据
import re  # 正则表达式,进行文字匹配
import urllib.request, urllib.error  # 指定URL,获取网页数据
import xlwt  # 进行excel操作



#影片详情连接的规则
findLink = re.compile(r'<a href="(.*?)">')  # 创建正则表达式对象,影片详情链接的规则

#影片图片
findImgSrc = re.compile(r'<img.*src="(.*?)"', re.S) #re.S 让换行符包含在字符中

#影片片名
findTitle = re.compile(r'<span class="title">(.*)</span>')

#影片评分
findRating = re.compile(r'<span class="rating_num" property="v:average">(.*)</span>')

#评价人数
findJudge = re.compile(r'<span>(\d*)人评价</span>')

#一句话简介
findInq = re.compile(r'<span class="inq">(.*)</span>')

#影片相关内容
findBd = re.compile(r'<p class="">(.*?)</p>', re.S)



def main():
    baseurl = "https://movie.douban.com/top250?start="  #要爬取的网页链接
    # 1.爬取网页
    datalist = getData(baseurl)
    savepath = "豆瓣电影Top250.xls"    #当前目录新建XLS,存储进去
  
    # 3.保存数据
    #saveData(datalist,savepath)      
   

# 爬取网页
def getData(baseurl):
    datalist = []  #用来存储爬取的网页信息
    for i in range(0, 10):  # 调用获取页面信息的函数,10次
        url = baseurl + str(i * 25)
        html = askURL(url)  # 保存获取到的网页源码
        # 2.逐一解析数据
        soup = BeautifulSoup(html, "html.parser")
        for item in soup.find_all('div', class_="item"):  # 查找符合要求的字符串,形成列表
            data = []  # 保存一部电影所有信息
            item = str(item)
            #影片详情连接
            link = re.findall(findLink, item)[0]       # re库用来通过正则表达式查找指定的字符串
            data.append(link)                          #添加链接

            imgSrc = re.findall(findImgSrc, item)[0]
            data.append(imgSrc)                        #添加图片

            titles = re.findall(findTitle, item)       #片名可能只有中文名没有外文名
            if (len(titles) == 2):
                ctitle = titles[0]                     #添加中文名
                data.append(ctitle)
                otitle = titles[1].replace("/", "")    #去掉无关字符
                data.append(otitle)                    #添加外文名
            else:
                data.append(titles[0])
                data.append(' ')                       #如果没有外文名就留空

            rating = re.findall(findRating, item)[0]
            data.append(rating)                        #添加评分

            judgeNum = re.findall(findJudge, item)[0]
            data.append(judgeNum)                      #添加评分人数

            inq = re.findall(findInq, item)
            if len(inq) != 0:
                inq = inq[0].replace("。", "")         #去掉句号
                data.append(inq)                       #添加一句话简介
            else:
                data.append(" ")

            bd = re.findall(findBd, item)[0]          #电影详细信息
            bd = re.sub('<br(\s+)?/>(\s+)?', "", bd)  #去掉<br/>
            # bd = re.sub('/', "", bd)
            data.append(bd.strip())                   #去掉空格

            datalist.append(data)                     #把处理好的电影信息放入datalist

    return datalist


# 得到指定一个URL的网页内容
def askURL(url):
    head = {  # 模拟浏览器头部信息,向豆瓣服务器发送消息
        "User-Agent": "Mozilla / 5.0(Windows NT 10.0; Win64; x64) AppleWebKit / 537.36(KHTML, like Gecko) Chrome / 80.0.3987.122  Safari / 537.36"
    }
    # 用户代理,表示告诉豆瓣服务器,我们是什么类型的机器、浏览器(本质上是告诉浏览器,我们可以接收什么水平的文件内容)

    request = urllib.request.Request(url, headers=head)
    html = ""
    try:
        response = urllib.request.urlopen(request)
        html = response.read().decode("utf-8")
    except urllib.error.URLError as e:
        if hasattr(e, "code"):
            print(e.code)
        if hasattr(e, "reason"):
            print(e.reason)
    return html


# 保存数据到表格
def saveData(datalist,savepath):
    print("save.......")
    book = xlwt.Workbook(encoding="utf-8",style_compression=0) #创建workbook对象
    sheet = book.add_sheet('豆瓣电影Top250', cell_overwrite_ok=True) #创建工作表
    col = ("电影详情链接","图片链接","影片中文名","影片外国名","评分","评价数","概况","相关信息")
    for i in range(0,8):
        sheet.write(0,i,col[i])  #列名
    for i in range(0,250):
        # print("第%d条" %(i+1))       #输出语句,用来测试
        data = datalist[i]
        for j in range(0,8):
            sheet.write(i+1,j,data[j])  #数据
    book.save(savepath) #保存

if __name__ == "__main__":  # 当程序执行时
    # 调用函数
     main()
     print("爬取完毕!")

这样我们的爬虫就爬取完毕了,我这里只是以豆瓣榜单为例,这个方法对于爬取其他网页也同样适用。这样做信息收集是特别方便,会大大提高工作效率。

有问题的,不懂的可以在评论区提出,或者私信我,看到就会回复。

最后关于两种存储方式:存储到Excel和存储到sqlite数据库,两种存储方式可以选择一种。我这里写的是存储数据到Excel的,如果需要存储数据库源代码的可以私信我!

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,108评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,699评论 1 296
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,812评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,236评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,583评论 3 288
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,739评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,957评论 2 315
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,704评论 0 204
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,447评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,643评论 2 249
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,133评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,486评论 3 256
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,151评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,108评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,889评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,782评论 2 277
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,681评论 2 272

推荐阅读更多精彩内容