爬虫入门实践之爬豆瓣Top250案例

爬虫的四大步骤

  1. 获取网页源代码
  2. 获取标签(tag)
  3. 正则表达式匹配
  4. 保存数据

获取网页源代码

常用的有urllib的python自带库还有第三方库requests

  1. urllib库
#导包
import os
import time
import urllib.request
#爬取指定url网页
header = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.101 Safari/537.36'}
request = urllib.request.Request(url=surl,headers = header)#伪装成浏览器访问方式
html = urllib.request.urlopen(request)#打开请求信息所得数据
htmltxt = html.read()#读取网页数据  转换成字符串类型
#print(type(htmltxt))
#print(htmltxt)
  1. requests库
#请求
import requests
url = 'https://movie.douban.com/typerank?type_name=%E5%89%A7%E6%83%85&type=11&interval_id=10:0&action='#网址
headers = {user-agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.111 Safari/537.36'}#请求头,用于伪装成浏览器用户访问

html = requests.get(url=url,headers=headers)#发出一个请求
#响应
print(html.text)#将请求所得数据转换成字符串数据,与urllib库的html.read()作用相同        

获取标签(tag)

给大家说一下爬虫的对象变化:
首先请求得到一个response对象,然后urlopen()打开,read()方法读取,用BeautifulSoup解析成改对象,然后改对象有find(),find_all()等方法去获取网页具体标签下的数据,生成的是标签(tag)对象,tag对象可以调用这两个方法来一层一层的爬取网页,或者用正则表达式爬的更细更符合自己的要求一些。

解析要用到BeautifulSoup这个库,它的用法大家可以参考大佬博主的这篇博文:https://blog.csdn.net/weixin_43930694/article/details/90142678?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param

#解析-》基础的简单的该库的方法,详细的参考上面给出的博文或者自行查看
from bs4 import BeautifulSoup
soup = BeautifulSoup(html.text,'html.parser')#soup是个BeautifulSoup对象,参数第二个是python自带的解析库,也可以用第三方库,自行csdn
items = soup.find('ul',class_ = 'nav_list').find('ul').find_all('li')	#一层一层往下爬
for item in items:
    kind = item.find('a')
    print('分类:'+kind.text.strip())

正则表达式匹配

参考以前写的或者自行百度:自己写的正则和一些常用函数用法
正则表达式的一些查询方法

保存数据

一般都是爬下来保存成文档或者json格式或者别的数据方法比较多,案例用的是sqlite3数据库和excel表格保存到。l

案例

有个错误就是index超出范围,然后我把循环里面改大了一点,但是我爬不了豆瓣,给我封了。难过。
这是错误和运行结果:
这一片数字也有讲究:403就是禁止访问的意思,可以自己百度:status_code
这个错误好多次遇到,mapreduce也遇到过,可以自己改一下index

from bs4 import BeautifulSoup
import urllib.request,urllib.error
import re
import sqlite3
import xlwt#进行excel操作
def main():
    baseUrl = "http://movie.douban.com/top250?start="
    #爬取网页,解析数据
    dataList = getData(baseUrl)

    savePath = ".\\豆瓣电影Top250.xls"
    #savePath = "movies.db"

    #保存数据
    saveData(dataList,savePath)
    #savedb (dataList,savePath)

#------正则表达式------#
findLink = re.compile(r'<a href="(.*?)">',re.S)  #链接
findName = re.compile(r'<span class="title">(.*?)</span>',re.S)  #电影名字
findRating = re.compile(r'<span class="rating_num" property="v:aerage">(.*?)</span>',re.S) #评分
findInq = re.compile(r'<span class="inq">(.*?)</span>',re.S) #下面小标题
findCount = re.compile(r'<span>(.*?)人评价</span>',re.S)  #评分人数
findInf = re.compile(r'<p class="">(.*?)</p>',re.S)  #电影信息


#---爬取网页---#
def getData(baseUrl):
    dataList = []
    for i in range(10):
        html = askUrl(baseUrl + str(i * 25))
        #每条解析数据
        bs = BeautifulSoup(html,'html.parser')
        for item in bs.find_all('div',class_='item'):
            data = []
            item = str(item)
            #链接
            link = re.findall(findLink,item)[0]
            #名字
            name = re.findall(findName,item)
            if len(name) == 1:
                cName = name[0]
                fName = " "
            else:
                name[1] = name[1].replace("/","")
                cName = name[0]
                fName = name[1]
            #评分
            rating = re.findall(findRating,item)[0]
            #标题
            inq = re.findall(findInq,item)
            if len(inq) < 1:
                inq = " "
            else:
                inq = inq[0]
            #评分人数
            racount = re.findall(findCount,item)[0]
            #电影信息
            inf = re.findall(findInf,item)[0]
            inf = re.sub("...<br(\s+)?/>(\s?)"," ",inf)
            inf = re.sub("/"," ","inf")
            inf = inf.strip()
            #添加一部电影的信息到data
            data.append(link)
            data.append(cName)
            data.append(fName)
            data.append(rating)
            data.append(inq)
            data.append(racount)
            data.append(inf)
            dataList.append(data)
    return dataList
#爬取指定的url
def askUrl(url):
    head = {"User-Agent" : ""}
    request = urllib.request.Request(url = url,headers = head)
    http = " "
    try:
        response = urllib.request.urlopen(request)
        http = response.read().decode('utf-8')
    except urllib.error.URLError as e:
        if hasattr(e,"code"):
            print(e.code)
        if hasattr(e, "reson"):
            print(e.reson)
    return http

#保存数据
def saveData(dataList,savePath):
    woke = xlwt.Workbook('utf-8,style_compression=0')#创建一个工程,参数:编码样式压缩效果
    sheet = woke.add_sheet('豆瓣电影Top250',cell_overwrite_ok = True)#创建一个表,参数:表名,覆盖原单元格的参数
    #列名
    col = ('链接','中文名字','英文名字','评分','标题','评分人数','概括')
    #遍历列名,并写入
    for i in range(7):
        sheet.write(0,i,col[i])
    #遍历数据并写入
    for i in range(0,251):
        for j in range(7):
            sheet.write(i+1,j,dataList[i][j])
            print("第%n条数据:"%(i+1))
    #保存数据到保存路径
    woke.save(savePath)
    print("保存完毕!")

#保存到数据库
def savedb(dataList,dataPath):
    initdb(dataPath)#新建表
    conn = sqlite3.connect(dataPath)#建立连接
    cur = conn.cursor()#建立游标
    #开始保存数据
    for data in dataList:
        for index in range(len(data)):
            #在每条数据的两端加上双引号
            data[index] = str('"' + data(index) + '"')
        #用 , 拼接数据
        newstr = ','.join(data)
        #sql语句
        sql = "insert into movie(info_link,cname,fname,rating,inq,racount,inf)values(%s)" %(newstr)
        print(sql)
        #执行sql
        cur.excute(sql)
        #提交事务
        conn.commit()
    cur.close()#关闭游标
    conn.close()#关闭连接
    print('保存完毕!')

#新建sqlite3的表
def initdb(dataPath):
    conn = sqlite3.connect(dataPath)
    cur = conn.cursor()#打开游标
    sql = '''
        create table movie(
        id Integer primary key autoincrement,
        nfo_link text,
        name varchar,
        name varchar,
        ating varchar,
        nq text,
        acount varchar,
        nf text
        )
    '''
    cur.execute(sql)
    conn.commit()
    cur.close()
    conn.close()
if __name__ == '__main__':
    main()
            
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值