关于用python爬虫——一个例子看爬虫

一个例子来展示python爬虫的编写流程

首先是编写爬虫需要的几个库

from bs4 import BeautifulSoup
import re
import urllib.request,urllib.error
import xlwt 
import sqlite3

其中bs4和xlwt是需要导入的库,在命令提示符窗口输入指令

pip install bs4
pip install xlwt

就能导入这两个库,记得要在联网的情况下完成上述操作

其他的三个库都是自带的库,无需导入就能使用。

关于xlwt和sqlite库

这个库是用来将爬取到的数据存储到excel表格中的一个库

如果不需要存储到excel表格中也可以存储到数据库中

使用的是sqlite3这个库

下面我的代码只有将数据存入excel表格中的操作,关于存入数据库的方面并未涉及。

主函数的部分

def main():
    baseurl = "https://movie.douban.com/top250?start="
    #爬取数据
    datalist = getData(baseurl)
    #保存数据
    savepath = "F:爬虫练习(豆瓣电影排行).xls"    #数据保存的路径
    saveData(datalist,savepath)

baseurl就是你想要爬取数据的网站url。

getData函数就是用来爬取数据的函数,后面会详细说明。

saveData函数是用来存储爬取到的数据的函数,后面也会详细说明。

那个savepath的地址建议使用绝对地址,因为使用相对地址的话可能会存在找不到文件位置的情况,所以谨慎使用相对地址。

正则表达式的内容

#超链接
findLink = re.compile(r'<a href="(.*?)">')
#图片
findImgSrc = re.compile(r'<img.*src="(.*?)"',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)

我们想要什么数据就需要利用正则表达式来获取它们

前面的命名可以按照自己的习惯来命名

后面则是调用re库来实现正则表达式

其中 r 表示后面的转义字符都不考虑,当作文本输出来

re.S的意思就是不考虑换行符,让他们在一行里输出

正则表达式救之这些括号里面的东西,在括号的两边则是网页代码中,每个方面都相同的部分,相同的东西都可以统一写在括号外面

其中正则表达式的内容在这里就不过多赘述了,有这方面学习期望的同学可以自己去找找相关博客或者学习视频

获取数据部分

def getData(baseurl):
    datalist = []
    #获取每个页面的信息条数
    for i in range(0,10):
        #针对不同的页面由不同的写法,这个只针对豆瓣电影排行这个网页
        url = baseurl + str(i*25)
        html = askURL(url)         #保存获取到的网页源码
        #逐一解析网页数据
        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)   #中文名
                etitle = titles[1].replace("/","")   #将外文名前面的/号去掉
                data.append(etitle)   #外文名
            else:
                data.append(titles)
                data.append(' ')    #留空,如果没有外文名就空着,不能不写这一段,不然可能会导致后期导出数据错位       
            rating = re.findall(findRating,item)[0]
            data.append(rating)        #添加评分
            judge = re.findall(findJudge,item)[0]
            data.append(judge)         #添加评价人数
            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 = str(bd)
            bd = re.sub('<br(\s+)?/>(\s+)?',"",bd)   #去掉br
            bd = re.sub('/'," ",bd)    #去掉空格
            data.append(bd.strip())   #去掉前后的空格           #添加详细信息
            datalist.append(data)    #把一部电影的全部信息都存到datalist里面去
    #返回一个网页上获取的数据列表
    return datalist

获取网页及部分异常处理

def askURL(url):
    # 用户代理,发送请求的时候让服务器认为我们是一个网页而不是一个程序,告诉服务器我们是一个什么类型的机器,可以获得什么水平的文件内容
    head = {                 #模拟浏览器头部信息,向服务器发送消息     #每个不同的项目需要获取的head也不同
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3863.400 QQBrowser/10.8.4334.400"
    }

    request = urllib.request.Request(url,headers=head)
    html = ""
    #为了防止错误,异常处理
    try:
        response = urllib.request.urlopen(request)
        html = response.read().decode("utf-8")
        # print(html)
    except urllib.error.URLError as e:
        if hasattr(e,"code"):
            print(e.code)
        if hasattr(e,"reason"):
            print(e.reason)
    return html

head的获取方式如下:

进入想要爬取的网站,按下f12
选择Network
在这里插入图片描述
点击页面刷新
加载3s后点击上方红色圆点,鼠标点击选中途中红色圈圈部分
在这里插入图片描述
选择下方那条信息,选中Headers这一栏
在这里插入图片描述
我们能看到这里面有很多的数据,但是我们不需要知道这每一条数据是什么意思,我们只需要找到我们想要的这一条数据就行了

往下滑找到这一行代码
在这里插入图片描述
将这行代码全部复制到python程序的head变量中就完成了

注意!复制的这行代码不能有其他字符,例如空格等,不然会报错,也不能换行

接下来是保存数据的函数

def saveData(datalist,savepath):
    book = xlwt.Workbook(encoding="utf-8",style_compression=0)   #创建workbook对象
    sheet = book.add_sheet("豆瓣电影排行",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)
    

我们需要先把每一列的列名给设置好,方便我们的查看

其中关于xlwt库的内容这里也不多做赘述,想学习的同学可以自行去网上搜索学习

下面是全部代码

from bs4 import BeautifulSoup
import re
import urllib.request,urllib.error
import xlwt
import sqlite3

def main():
    baseurl = "https://movie.douban.com/top250?start="
    datalist = getData(baseurl)

    savepath = "F:\爬虫存储的数据\爬虫练习(豆瓣电影排行).xls"
    saveData(datalist,savepath)
    
findLink = re.compile(r'<a href="(.*?)">')
findImgSrc = re.compile(r'<img.*src="(.*?)"',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 getData(baseurl):
    datalist = []
    for i in range(0,10):
        url = baseurl + str(i*25)
        html = askURL(url)
        soup = BeautifulSoup(html,"html.parser")
        for item in soup.find_all('div',class_="item"):
            data = []
            item = str(item)
 
            link = re.findall(findLink,item)[0]
            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)
                etitle = titles[1].replace("/","")
                data.append(etitle)
            else:
                data.append(titles)
                data.append(' ')  
            rating = re.findall(findRating,item)[0]
            data.append(rating)
            judge = re.findall(findJudge,item)[0]
            data.append(judge)
            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 = str(bd)
            bd = re.sub('<br(\s+)?/>(\s+)?',"",bd)
            bd = re.sub('/'," ",bd)
            data.append(bd.strip())
            
            datalist.append(data)
    return datalist

def askURL(url):
    head = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3863.400 QQBrowser/10.8.4334.400"
    }
    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):
    book = xlwt.Workbook(encoding="utf-8",style_compression=0)
    sheet = book.add_sheet("豆瓣电影排行",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("爬取完毕")

以上内容均来自于b站李巍老师的课程

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值