美文网首页程序员
第一个python爬虫

第一个python爬虫

作者: Y先生说 | 来源:发表于2017-10-03 11:51 被阅读795次

    树莓派

    上个月月末,入手了第一台树莓派。树莓派是什么?没有决定购买之前,只见过同事在玩,觉得很神奇。研究后才知道这是一个微型电脑。

    具体的就不在这里说了。到手之后折腾了两天,在树莓派3b上搭建一套ubuntu系统。嗯,这也是我第一次搭建和使用ubuntu。

    做什么呢

    树莓派到手了,用来做什么呢?

    一开始打算弄一弄深度学习,尝试了一下tensorflow和caffe,都失败了,装不上。这套专为树莓派使用的Ubuntu貌似有不少问题。

    那就做点简单的吧,比如爬虫。

    之前做过的爬虫是java版本的webmagic,感觉不好用。这次打算尝试一下python。反正国庆假期多,就趁机会把python也学习一下。

    准备工作

    python:

    教程:http://www.runoob.com/python3/python3-tutorial.html

    了解基本的语法,以及linux下python的使用,包括版本切换、执行python文件等。

    Beautiful Soup:

    教程:https://www.crummy.com/software/BeautifulSoup/bs4/doc/index.zh.html

    了解使用它获取html内容的相关方法。

    MySQL-python

    python连接mysql:http://www.cnblogs.com/fnng/p/3565912.html

    爬什么内容

    在简书搜了一下,发现一个可以快速参考的文章:
    http://www.jianshu.com/p/be891e7e96e2

    写得比较详细,就决定依样画葫芦爬简书吧。

    代码实现

    表结构:

    /*
    SQLyog Ultimate v12.4.3 (64 bit)
    MySQL - 5.7.13-log : Database - scrapy_jianshu
    *********************************************************************
    */
    
    /*!40101 SET NAMES utf8 */;
    
    /*!40101 SET SQL_MODE=''*/;
    
    /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
    /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
    /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
    /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
    CREATE DATABASE /*!32312 IF NOT EXISTS*/`scrapy_jianshu` /*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci */;
    
    USE `scrapy_jianshu`;
    
    /*Table structure for table `jianshu_article` */
    
    DROP TABLE IF EXISTS `jianshu_article`;
    
    CREATE TABLE `jianshu_article` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `article_type` varchar(30) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '文章分类',
      `article_id` varchar(30) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '简书上的文章id',
      `title` varchar(150) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
      `author` varchar(30) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
      `author_id` varchar(30) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '作者id',
      `abstract` text COLLATE utf8mb4_unicode_ci COMMENT '摘要',
      `content` mediumtext COLLATE utf8mb4_unicode_ci,
      `like_count` int(6) DEFAULT NULL COMMENT '点赞数',
      `reward_count` int(4) DEFAULT NULL COMMENT '打赏数',
      `comment_count` int(6) DEFAULT NULL COMMENT '评论数',
      `link` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '文章链接',
      `read_count` int(11) DEFAULT NULL COMMENT '阅读量',
      `create_time` datetime DEFAULT NULL COMMENT '发表时间',
      PRIMARY KEY (`id`),
      UNIQUE KEY `article_id` (`article_id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=29782 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
    
    /*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
    /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
    /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
    /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
    
    

    python源码:

    #!/usr/bin/env python
    #coding=utf-8
    
    import requests
    from bs4 import BeautifulSoup
    import pymysql
    from datetime import datetime
    
    # 打开数据库连接
    db = pymysql.connect("192.168.0.102","root","root","scrapy_jianshu",charset="utf8")
    
    # 使用 cursor() 方法创建一个游标对象 cursor
    cursor = db.cursor()
    
    # MySQLdb正常情况下会尝试将所有的内容转为latin1字符集处理,所以设置编码如下
    cursor.execute('SET NAMES utf8;') 
    cursor.execute('SET CHARACTER SET utf8;')
    cursor.execute('SET character_set_connection=utf8;')
    
    
    # 推荐分类
    recommendations='http://www.jianshu.com/recommendations/collections?page=%d&order_by=recommend'
    
    
    # 简书分类
    base_urls=[]
            
    
    # 抓取函数
    def scrapy_artilce(url):
        add_url=0
        n=1000#每个专题抓取最受欢迎的前1000篇文章
        while(n>0):
            try:
                add_url += 1
                n = n-1
                response=requests.request('get',url% add_url)
                page=response.content
                soup=BeautifulSoup(page,'html.parser')
                type="'"+soup.select("a.name")[0].get_text() #文章分类
                article_list = [article for article in soup.select("div.content")]
                for article in article_list:
                    author=article.select("a.blue-link")[0].get_text()#文章作者
                    author_id=article.select("a.blue-link")[0].get('href')#作者id
                    title=article.select("a.title")[0].get_text()#文章标题
                    article_id=article.select("a.title")[0].get('href')#文章id
                    abstract=article.select("p.abstract")[0].get_text()#文章摘要
                    link="http://www.jianshu.com"+article_id#文章链接
    
                    # 抓取文章正文
                    response1=requests.request('get',link)
                    page1=response1.content
                    soup1=BeautifulSoup(page1,'html.parser')
    
                    content=''
                    if len(soup1.select('.show-content')):
                        content=soup1.select('.show-content')[0].get_text()#文章内容
    
                    read=0 #文章阅读量
                    if len(article.select(".ic-list-read")):
                            read=article.select(".ic-list-read")[0].find_parent().get_text() #文章阅读量
                    read=int(read)
    
                    comment=0 #文章评论量
                    if len(article.select(".ic-list-comments")):
                            comment=article.select(".ic-list-comments")[0].find_parent().get_text() #文章评论量
                    comment=int(comment)
    
                    like=0 #文章点赞量
                    if len(article.select(".ic-list-like")):
                            like=article.select(".ic-list-like")[0].find_parent().get_text() #文章点赞量
                    like=int(like)
    
                    reward=0 #文章赞赏数量
                    if len(article.select(".ic-list-money")):
                            reward=article.select(".ic-list-money")[0].find_parent().get_text() #文章赞赏数量
                    reward=int(reward)
    
                    create_time=article.select(".time")[0].get('data-shared-at')#发表时间
                    create_time=create_time.replace('T',' ')
                    create_time=create_time.replace('+08:00','')
                    create_time=datetime.strptime(create_time,"%Y-%m-%d %H:%M:%S")
    
                    sql="insert into jianshu_article (title,article_id,article_type,author,author_id,abstract,like_count,reward_count,comment_count,link,read_count,content,create_time) \
                    values ('%s','%s',%s','%s','%s','%s','%d','%d','%d','%s','%d','%s','%s')" % \
                    (title,article_id,type,author,author_id,abstract,like,reward,comment,link,read,content,create_time)
                    
                    try:
                        cursor.execute(sql)
                        db.commit()
                    except Exception as e:
                        print('错误sql:'+sql)
                        print(e)
                        db.rollback()
            except Exception as e:
                print(e)
    
    # 开始抓取
    add_url=1
    while(add_url<50):#推荐专题没有超过50个
        try:
            response=requests.request('get',recommendations% add_url)
            page=response.content
            soup=BeautifulSoup(page,'html.parser')
            tyle_list=[_type for _type in soup.select("div.collection-wrap")]
            
            for _type in tyle_list:
                _type_id=_type.select(".avatar-collection")[0].find_parent().get('href')
                type_link='http://www.jianshu.com'+_type_id+'?order_by=top&page=%d'
                base_urls.append(type_link)
            
            add_url +=1
        except Exception as e:
                print(e)
    
    for _type in base_urls:
        scrapy_artilce(_type)
    
    # 关闭数据库连接
    db.close()
    

    总结

    这个简单的爬虫在树莓派上跑了将近两天,按照各个专题内文章的点赞数排序,已经抓取了7w+文章。

    树莓派的好处是便宜,200多块钱就可以搭建好的一台linux服务器,而且耗电少,持续运行也不怎么发热。

    后来又想爬心声论坛的内容,于是就又写了一个简单点的:

    #!/usr/bin/env python
    #coding=utf-8
    
    import requests
    from bs4 import BeautifulSoup
    import pymysql
    from datetime import datetime
    import re
    
    # 打开数据库连接
    db = pymysql.connect("192.168.0.102","root","root","scrapy_jianshu",charset="utf8")
    
    # 使用 cursor() 方法创建一个游标对象 cursor
    cursor = db.cursor()
    
    # MySQLdb正常情况下会尝试将所有的内容转为latin1字符集处理,所以设置编码如下
    cursor.execute('SET NAMES utf8;') 
    cursor.execute('SET CHARACTER SET utf8;')
    cursor.execute('SET character_set_connection=utf8;')
    
    
    # 按点击最多排序
    xinsheng_base_url='http://xinsheng.huawei.com/cn/index.php?app=forum&mod=List&act=index&class=461&order=viewcount&type=&sign=&special=&p=%d'
            
    
    # 抓取函数
    def scrapy_artilce(url):
        add_url=0
        while(True):
            try:
                add_url += 1
                response=requests.request('get',url% add_url)
                page=response.content
                soup=BeautifulSoup(page,'html.parser')
                type="'"+'' #文章分类
                article_list = [article for article in soup.select("div.font_box")]
                for article in article_list:
                    author=article.select(".pro")[0].select("a")[0].get_text()#文章作者
                    if len(article.select(".space_rz_blue")):
                        author=article.select(".space_rz_blue")[0].find_parent().get_text()#文章作者
                        author=author.replace(' ','')
    
                    author_id=''#作者id
    
                    title=article.select("p")[0].select('font')[0].select('a')[0].get_text()#文章标题
                    
                    article_id=''#文章id
                    abstract=''#文章摘要
    
                    
                    link=article.select("p")[0].select('font')[0].select('a')[0].get('href')#文章链接
    
                    # 抓取文章正文
                    response1=requests.request('get',link)
                    page1=response1.content
                    soup1=BeautifulSoup(page1,'html.parser')
    
                    content=''
                    if len(soup1.select('.bbs_info_right_text')):
                        content=soup1.select('.bbs_info_right_text')[0].get_text()#文章内容
                        if len(content) == 0:
                            content=soup1.select('.bbs_info_right_text')[1].get_text()
    
                    read=0 #文章阅读量
                    comment=0 #文章评论量
                    if len(article.select('.pro_width')):
                            read=article.select('.pro_width')[0].get_text() #文章阅读量
                    
                    if len(article.select('.iconReply')):
                            comment=article.select('.iconReply')[0].find_parent().get_text() #文章评论量
    
                    read=int(read)
                    comment=int(comment)
    
                    like=0 #文章点赞量
                    reward=0 #文章赞赏数量
                    
                    create_time='1970-01-01'
                    if len(article.select('.pro')):
                        create_time=article.select('.pro')[0].get_text()#发表时间
                    
                    create_time= re.findall(r"\d{4}-\d{2}-\d{2}",create_time)[0]
                    create_time=datetime.strptime(create_time,"%Y-%m-%d")
    
    
                    sql="insert into xinsheng_article (title,article_id,article_type,author,author_id,abstract,like_count,reward_count,comment_count,link,read_count,content,create_time) \
                    values ('%s','%s',%s','%s','%s','%s','%d','%d','%d','%s','%d','%s','%s')" % \
                    (title,article_id,type,author,author_id,abstract,like,reward,comment,link,read,content,create_time)
                    
                    #print(sql)
                    
                    try:
                        cursor.execute(sql)
                        db.commit()
                    except Exception as e:
                        print('错误sql:'+sql)
                        print(e)
                        db.rollback()
                    
            except Exception as e:
                print(e)
    
    # 开始抓取
    scrapy_artilce(xinsheng_base_url)
    
    # 关闭数据库连接
    db.close()
    

    到目前为止,也已经从心声论坛上抓取到了4w+文章。后续可以在这些数据的基础之上做一些查询和分析了。

    相关文章

      网友评论

        本文标题:第一个python爬虫

        本文链接:https://www.haomeiwen.com/subject/uinxyxtx.html