本文来自网易云社区

作者:王贝

小学生现在都在学python了,作为专业程序员当然不能落下了,所以,快马加鞭,周六周末在家学起了python3,python3的基本语法比较简单,相比于Java开发更加敏捷,python3的基础就不讲了,这里主要讲下我这里的爬虫小程序的实现逻辑吧

上下模块图:

一目了然,总体上就是这5步,涉及到python3的requests,bs4,re,sqlalchemy这四个模块。

(1)requests:

是一个很强大的http客户端库,提供了丰富的api,比如发一个get请求:

with requests.get(url,params={},headers={}) as rsp:
   res.text   #返回值文本内容

发一个入参为json的post请求:

with requests.post(url,json={},headers={}) as rsp:
   res.text #返回值文本内容

等等。

这里值得说一下,为什么用with as,with会先执行__enter__()方法,其返回值就是as,requests里返回值就是rsp,当with as 这一逻辑行执行结束时,就会执行__exit__()方法,requests里__exit__()方法将request close掉了,这就是程序没有显示调用close的原因。下面程序里会有一个例子彰显with as的功能。

requests还有很多强大的功能,参考:https://www.cnblogs.com/lilinwei340/p/6417689.html。

(2)bs4 BeatifulSoup

学过java的都知道java有个jsoup,jsoup就是对html模版进行解析,变成各个标签集合,这里bs4和jsoup如出一辙,api也基本一致,比如,一下html代码,我们想获取新闻,地图,视频,贴吧 这些内容,只要:

soup=BeautifulSoup(html,'html.parser')
atags=soup.find('div',{'id':'u1'}).findChilren('a',{'class':'mnav'})
values=[]for atag in atags:
   values.append(atag.text)

以上程序即可实现我们的要求,python解析html的还有一个scrapy框架的xpath,以后分享scrapy时再讲。

<html>
<head>
    <meta http-equiv=content-type content=text/html;charset=utf-8>
    <meta http-equiv=X-UA-Compatible content=IE=Edge>
    <meta content=always name=referrer>
    <link rel=stylesheet type=text/css href=http://s1.bdstatic.com/r/www/cache/bdorz/baidu.min.css>
    <title>百度一下,你就知道</title></head>
<body link=#0000cc>
<div id=wrapper>
    <div id=head>
        <div >            <div >                <div >                    <div id=lg><img hidefocus=true src=//www.baidu.com/img/bd_logo1.png width=270 height=129></div>
                    <form id=form name=f action=//www.baidu.com/s >                        <input type=hidden name=ie value=utf-8> <input type=hidden name=f value=8> <input type=hidden
                                                                                                          name=rsv_bp
                                                                                                          value=1>
                        <input type=hidden name=rsv_idx value=1> <input type=hidden name=tn value=baidu><span
                                ><input id=kw name=wd >                                                           autocomplete=off autofocus></span><span
                                ><input type=submit id=su value=百度一下 ></span></form>
                </div>
            </div>
            <div id=u1><a href=http://news.baidu.com name=tj_trnews >                                                                                         name=tj_trhao123 >                <a href=http://map.baidu.com name=tj_trmap >                                                                                >                        href=http://tieba.baidu.com name=tj_trtieba >                <noscript><a
                        href=http://www.baidu.com/bdorz/login.gif?login&tpl=mn&u=http%3A%2F%2Fwww.baidu.com%2f%3fbdorz_come%3d1
                        name=tj_login >                <script>document.write('<a href="http://www.baidu.com/bdorz/login.gif?login&tpl=mn&u=' + encodeURIComponent(window.location.href + (window.location.search === "" ? "?" : "&") + "bdorz_come=1") + '" name="tj_login" >登录</a>');</script>
                <a href=//www.baidu.com/more/ name=tj_briicon >        </div>
    </div>
    <div id=ftCon>
        <div id=ftConw><p id=lh><a href=http://home.baidu.com>关于百度</a> <a href=http://ir.baidu.com>About Baidu</a></p>
            <p id=cp>©2017 Baidu <a href=http://www.baidu.com/duty/>使用百度前必读</a>  <a
                    href=http://jianyi.baidu.com/ >                    src=//www.baidu.com/img/gs.gif></p></div>
    </div>
</div>
</body>
</html>

(3) re

re正则模块很强大,有match search sub replace这些api,每个都有自己的特长,可以参考:http://www.runoob.com/python3/python3-reg-expressions.html

(4) sqlalchemy

一款python的数据库orm框架,用了下,很好用,有点类似于java 的hibernate,但更灵活。

说了这么多,该帖下爬虫脚本的代码了,下面是目录结构,毕竟也是专业程序员,不能写的一团糟,也要讲究架构,哈哈。

------youku_any #包名

--------------datasource.py #专门管理数据源session

--------------youkubannerdao.py #程序里抓取的优酷banner信息,这个是dao层

--------------youkuservice.py   #不用说了,业务逻辑

还有一件事情,就是建表,不多说了:

CREATE TABLE `youku_banner` (  `id` bigint(22) NOT NULL AUTO_INCREMENT,  `type` int(2) NOT NULL, #优酷banner类型 1:电视 2:电影 3.综艺 
  `year` int(4) NOT NULL,  `month` int(2) NOT NULL,  `date` int(2) NOT NULL,  `hour` int(2) NOT NULL,  `minute` int(2) NOT NULL,  `img` varchar(255) DEFAULT NULL,  `title` varchar(255) DEFAULT NULL,  `url` varchar(255) DEFAULT NULL,  `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,  PRIMARY KEY (`id`),  KEY `idx_uniq` (`year`,`month`,`date`,`hour`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=83 DEFAULT CHARSET=utf8mb4

接下来就是代码实现了:

datasource.py

from sqlalchemy import create_enginefrom sqlalchemy.orm import sessionmaker

dburl = 'mysql+pymysql://root:123@localhost/youku?charset=utf8'#pool_size 置为100 session回收时间3600sds = create_engine(dburl,pool_size=100,pool_recycle=3600)

Session = sessionmaker(bind=ds)# session=Session()#创建session管理类class SessionManager():

    def __init__(self):
        self.session=Session()    def __enter__(self):
        return self.session    #连接池管理session,不需要显示close
    def __exit__(self, exc_type, exc_val, exc_tb):
        # session.close()
        print('not close')

youkubannerdao.py

from sqlalchemy import Sequence, Column, Integer, BigInteger, String, TIMESTAMP, textfrom sqlalchemy.ext.declarative import declarative_basefrom youku_any.datasource import SessionManager

Base = declarative_base()#继承基类Baseclass YoukuBanner(Base):

    #指定表名
    __tablename__ = 'youku_banner'     #定义字段映射关系
    id = Column(BigInteger, Sequence('id'), primary_key=True)
    type=Column(Integer)
    year = Column(Integer)
    month = Column(Integer)
    date = Column(Integer)
    hour = Column(Integer)
    minute = Column(Integer)
    img = Column(String(255))
    title = Column(String(255))
    url = Column(String(255))
    createTime = Column('create_time', TIMESTAMP)    def add(self):
        #with as 先执行SessionManager __enter__() 逻辑行结束执行__exit()__
        with SessionManager() as session:            try:
                session.add(self)
                session.commit()            except:
                session.rollback()    def addBatch(self,values):
        with SessionManager() as session:            try:
                session.add_all(values)
                session.commit()            except:
                session.rollback()    def select(self,param):
        with SessionManager() as session:            return session.query(YoukuBanner).select_from(YoukuBanner).filter(param)    def remove(self,parma):
        with SessionManager() as session:            try:
                session.query(YoukuBanner).filter(parma).delete(synchronize_session='fetch')
                session.commit()            except:
                session.rollback()    def update(self,param,values):
        with SessionManager() as session:            try:
                session.query(YoukuBanner).filter(param).update(values, synchronize_session='fetch')
                session.commit()            except:
                session.rollback()

youkuservice.py

import requestsimport jsonimport reimport datetimefrom bs4 import BeautifulSoupfrom sqlalchemy import textfrom youku_any.youkubannerdao import YoukuBannerdef getsoup(url):
    with requests.get(url, params=None, headers=None) as req:        if req.encoding != 'utf-8':
            encodings = requests.utils.get_encodings_from_content(req.text)            if encodings:
                encode = encodings[0]            else:
                encode = req.apparent_encoding
        encode_content = req.content.decode(encode).encode('utf-8')
        soup = BeautifulSoup(encode_content, 'html.parser')        return soupdef getbanner(soup):
    # soup = BeautifulSoup()
    # soup.findChild()
    bannerDivP = soup.find('div', {'id': 'm_86804', 'name': 'm_pos'})
    bannerScript = bannerDivP.findChildren('script', {'type': 'text/javascript'})[1].text
    m = re.search('\[.*\]', bannerScript)
    banners = json.loads(m.group())    for banner in banners:
        time = datetime.datetime.now()
        youkubanner = YoukuBanner(type=1, year=time.year, month=time.month, date=time.day, hour=time.hour,
                                  minute=time.minute,
                                  img=banner['img'], title=banner['title'], url=banner['url'])
        youkubanner.add() soup=getsoup('http://tv.youku.com/')
getbanner(soup) youkuBanner = YoukuBanner()
youkuBanner.remove(parma=text('id=67 or id=71'))
youkuBanner.update(param=text('id=70'),values={'title':YoukuBanner.title + '呼啸山庄'})for i in range(0,10000):
    youkuBanner.update(param=text('id=70'), values={'title': YoukuBanner.title + '呼啸山庄'})
    bannerList = youkuBanner.select(param=text('id > 66 and id < 77 order by id asc limit 0,7'))
    print("lines--------%d" % i)    # time.sleep(10)
    for banner in bannerList:
        print(banner.id,banner.minute,banner.img,banner.title)

到此,一个简答的爬虫脚本就写完了,周末两天的成果还是有点小满足,不过这只是python的冰山一脚,还有好多等着我们去探讨呢。

网易云免费体验馆,0成本体验20+款云产品!

更多网易研发、产品、运营经验分享请访问网易云社区

相关文章:
【推荐】 SpringBoot入门(一)——开箱即用

Python3下基于bs4和sqlalchemy的爬虫实现的更多相关文章

  1. 简单的python2.7基于bs4和requests的爬虫

    python的编码问题比较恶心. decode解码encode编码 在文件头设置 # -*- coding: utf-8 -*-让python使用utf8. # -*- coding: utf- -* ...

  2. python3下scrapy爬虫(第二卷:初步抓取网页内容之直接抓取网页)

    上一卷中介绍了安装过程,现在我们开始使用这个神奇的框架 跟很多博主一样我也先选择一个非常好爬取的网站作为最初案例,那么我先用屌丝必备网站http://www.shaimn.com/xinggan/作为 ...

  3. python3制作捧腹网段子页爬虫

    0x01 春节闲着没事(是有多闲),就写了个简单的程序,来爬点笑话看,顺带记录下写程序的过程.第一次接触爬虫是看了这么一个帖子,一个逗逼,爬取煎蛋网上妹子的照片,简直不要太方便.于是乎就自己照猫画虎, ...

  4. 基于Scrapy的B站爬虫

    基于Scrapy的B站爬虫 最近又被叫去做爬虫了,不得不拾起两年前搞的东西. 说起来那时也是突发奇想,想到做一个B站的爬虫,然后用的都是最基本的Python的各种库. 不过确实,实现起来还是有点麻烦的 ...

  5. 基于Node.js的强大爬虫 能直接发布抓取的文章哦

    基于Node.js的强大爬虫 能直接发布抓取的文章哦 基于Node.js的强大爬虫能直接发布抓取的文章哦!本爬虫源码基于WTFPL协议,感兴趣的小伙伴们可以参考一下 一.环境配置 1)搞一台服务器,什 ...

  6. 大数据下基于Tensorflow框架的深度学习示例教程

    近几年,信息时代的快速发展产生了海量数据,诞生了无数前沿的大数据技术与应用.在当今大数据时代的产业界,商业决策日益基于数据的分析作出.当数据膨胀到一定规模时,基于机器学习对海量复杂数据的分析更能产生较 ...

  7. CentOS 环境下基于 Nginx uwsgi 搭建 Django 站点

    因为我的个人网站 restran.net 已经启用,博客园的内容已经不再更新.请访问我的个人网站获取这篇文章的最新内容,CentOS 环境下基于 Nginx uwsgi 搭建 Django 站点 以下 ...

  8. 基于redis的简易分布式爬虫框架

    代码地址如下:http://www.demodashi.com/demo/13338.html 开发环境 Python 3.6 Requests Redis 3.2.100 Pycharm(非必需,但 ...

  9. 基于bs4库的HTML标签遍历方法

    基于bs4库的HTML标签遍历方法 import requests r=requests.get('http://python123.io/ws/demo.html') demo=r.text HTM ...

随机推荐

  1. Spring的DI(Dependency Injection)

    写在之前,作为正在学习的程序员,对于Spring理解比较差,给两个简单的定义大家看一下. 控制反转(Inversion of Control),是一个重要的面向对象编程的法则来削减计算机程序的耦合问题 ...

  2. iOS Programming Autorotation, Popover Controllers, and Modal View Controllers

    iOS Programming Autorotation, Popover Controllers, and Modal View Controllers  自动旋转,Popover 控制器,Moda ...

  3. LR脚本示例之参数_变量介绍

    Action(){ char *url = "127.0.0.1:1080"; char arr_url[1024]; //将url变量的值复制给p_url1参数 lr_save_ ...

  4. GoAccess安装和使用介绍

    使用文档参考地址:https://my.oschina.net/mrco/blog/181737https://www.fanhaobai.com/2017/06/go-access.html goa ...

  5. C#解析 json格式

    C# 解析 json JSON(全称为JavaScript Object Notation) 是一种轻量级的数据交换格式.它是基于JavaScript语法标准的一个子集. JSON采用完全独立于语言的 ...

  6. java面试题(杨晓峰)---第二讲Exception和Error有什么区别?

    本人总结: Exception和Error:正常问题和意外问题,以自行车举例:没气和爆胎. ①理解Throwable,Exception,Error的设计和分类. ②掌握哪些应用最广泛的子类, ③如何 ...

  7. MovieReview—Ghost in the Shell(攻壳机动队:笑脸男事件,个别的11人事件)

    AI with Wisdom         I have recently watched two films in the series of Ghost in the Shell, Smilin ...

  8. 陆教授浅谈5G毫米波手机天线技术的发展现状和未来的应用场景

    近日,香港城大电子工程学系讲座教授陆贵文教授荣获英国皇家工程院院士荣衔,以表彰他在推动天线研究的卓越贡献.他研发的天线由L形探针馈电微带天线.磁电耦极天线,以至5G毫米波手机天线等技术,均在天线领域影 ...

  9. Python-OpenCV中的cv2.inpaint()函数

    概念 修复是图像插值.数字修复算法在图像插值,照片恢复,缩放和超分辨率等方面具有广泛的应用. 大多数人会在家里放一些旧的退化照片,上面有一些黑点,一些笔画等.你有没有想过恢复它?我们不能简单地在绘画工 ...

  10. 使用EventLog组件保存Windows系统日志

    实现效果: 知识运用: EventLog类的CreateEventSource方法 //用于建立一个应用程序  使用指定的Sourc作为向本机上的日志中写入日志项的有效事件源 CreateEventS ...