【爬虫】菜鸟教程,支持翻页,存储

服务器

浏览数:123

2019-3-20

1、项目简介

豆瓣相信很多人都爬过,我也把我的方法拿出来交流学习,我也是菜鸟过来的,不会省略代码,此教程纯属娱乐,大神勿喷。

2、工具

  • requests
  • re
  • pygal
  • mysql
  • Anacond2

3、爬虫完整代码

# encoding:UTF-8
import re
import requests
import MySQLdb
from bs4 import BeautifulSoup

headers = {'User-Agent' :'Mozilla/5.0 (Windows NT 10.0; Win64; x64)'}


def getPage(get_url):
    r=requests.get(get_url)
    response = r.text
    return response
def filterpage():
    pageCode = getPage(get_url)
    pattern = re.compile('<em class="">(.*?)</em>.*?<span class="title">(.*?)</span>.*?<span class="rating_num" property="v:average">(.*?)</span>',re.S)
    items = re.findall(pattern,pageCode)
    pageStories = []
    for item in items:
        pageStories.append([item[0].strip(),item[1].strip(),item[2].strip()])
    return pageStories
def save_data():
    Dbdata=filterpage()
    db=MySQLdb.connect(host='localhost',user='root',passwd='******',db='movie',charset='utf8')
    cursor=db.cursor()
    for a in Dbdata:
        id=a[0]
        name=a[1]
        grade=a[2]
        #comment=a[3]
        value=[id,name,grade]
        cursor.execute('insert into movie_info values(%s,%s,%s)',value)
        db.commit()
def main():
    pageStories=filterpage()
    #print pageStories
    for story in pageStories:
        try:
            print u"序号:",story[0],u"电影名:",story[1], u"\t评分:", story[2]
        except:
            pass

if __name__ == '__main__':
    get_url = 'https://movie.douban.com/top250/'
    i=1
    while i < 11:
        main()
        save_data()
        print u'页码',i
        num = i * 25
        get_url = 'https://movie.douban.com/top250?start=' + str(num) + '&filter='
        i = i + 1

4、前期准备

  • install mysql
    我是在windows环境下跑爬虫的,用的是MySQL5.7,下载地址:https://dev.mysql.com/downloa…
  • 值得一提的是,mysql的安装,window版的mysql安装起来说实话还是比较麻烦的,我装了很久,没成功,最后选择下载压缩版安装。安装完之后,在mysql目录下创建my.ini配置文件,输入以下代码:
[mysqld] 
tmpdir=F:\mysql-5.7.18-winx64   # 安装目录
datadir=F:\mysql-5.7.18-winx64\data   # data目录,没有data目录请手动创建
early-plugin-load=""
skip-grant-tables
  • 点击保存,data目录是mysql初始化会用到的目录,一般是空目录,不然初始化不通过。特别是“ 服务没有报告任何错误。 请键入 NET HELPMSG 3534”错误。然后添加mysql的环境路径。
  • cmd输入:
cd F:\mysql-5.7.18-winx64\bin # 进入bin目录,不然有可能会报错
mysqld initialize  # 初始化命令
net start mysql    # 启动服务
  • 创建数据表,我们需要保存的数据有ID,评分grade,还有电影名name。
mysql>create database movie   # 创建movie数据库
mysql>use movie # 
mysql>create table movie_info (id varchar(100),name varchar(100),grade decimal(3,1));

5、目标网页分析

这个教程中,我们需要爬取豆瓣top250的电影名、序号和相应的评分。F12分析网页结构。找到有《肖申克的救赎》的代码处:

<em class="">1</em>   # 序号
.
.
.      
<span class="title">肖申克的救赎</span> # 电影名
.
.
.
<span class="rating_num" property="v:average">9.6</span>  # 评分

ok,往后翻,可以看到剩下的都是这类的结构,我们找到规律了,就可以想办法,把里面的东西给搞出来。
一般常用的有re模块和beautifulsoup模块,我是用re模块正则匹配,感觉正则更强大一点,漂亮汤模块用起来简单,但是速度慢。

6、代码分析

6.1 爬取页面代码

def getPage(get_url):            # 定义一个抓取网页的方法
    r=requests.get(get_url)      # get到目标网页
    response = r.text
    return response              # 返回抓取到的网页
  • 爬虫开始爬,就是给web服务器一个请求,然后抓取到返回信息。
  • HTTP 请求方法有 OPTIONS、GET、HEAD、post、PUT、DELETE、TRACE、CONNECT,其中比较常用的有get和post,其他的都不常见,判断请求方式很重要。自行百度。

6.2 页面代码处理

def filterpage():              # 页面处理方法
    pageCode = getPage(get_url)   #传参
    pattern = re.compile('<em class="">(.*?)</em>.*?<span class="title">(.*?)</span>.*?<span class="rating_num" property="v:average">(.*?)</span>',re.S)
    items = re.findall(pattern,pageCode)
    pageStories = []        # 定义一个空数组,用来存分离出来的数据
    for item in items:      # 迭代
        pageStories.append([item[0].strip(),item[1].strip(),item[2].strip()])# 去除空格
    return pageStories
  • 正则表达式,在程序刚开始,我们导入了python的re模块,这个模块专门处理正则匹配,详细教程点这里

我们用第一个(.*?)非贪婪匹配来匹配序号,接着用.*?贪婪匹配匹配不需要的代码,往后同样用非贪婪匹配来匹配我们需要的信息。

  • 接着用strip()方法去除空格。返回得到的字符串pageStories。

6.3 数据存储

def save_data(): 
    Dbdata=filterpage() #传参
    db=MySQLdb.connect(host='localhost',user='root',passwd='suyu.123',db='movie',charset='utf8') # 链接数据库
    cursor=db.cursor() # 定义游标
    for a in Dbdata:   # 迭代存储数据
        id=a[0]
        name=a[1]
        grade=a[2]
        value=[id,name,grade]
        cursor.execute('insert into movie_info values(%s,%s,%s)',value) # sql命令存数据
        db.commit()   # 别忘记提交变更
  • python操作mysql,感觉没啥好讲的了。。

6.4主函数

def main():
    pageStories=filterpage()   # 传参
    for story in pageStories:  # 迭代打印
        try:
            print u"序号:",story[0],u"电影名:",story[1], u"\t评分:", story[2]
        except:
            pass
  • 主函数主要是用来打印出我们抓取的数据。

6.5运行程序

if __name__ == '__main__':
    get_url = 'https://movie.douban.com/top250/' # 起始网页
    i=1
    while i < 11:
        main()                  # 运行主函数
        save_data()             # 运行存储函数
        print u'页码',i         # 
        num = i * 25
        get_url = 'https://movie.douban.com/top250?start=' + str(num) + '&filter='
        i = i + 1
  • 通过豆瓣top250的页面分析可以知道,总共有10页,所以我们设置i<11,整个豆瓣电影top250的网址很有规律,第一页是:https://movie.douban.com/top250,第二页就是:https://movie.douban.com/top2…,这样的网页有规律,我喜欢,所以我们可以用迭代来表示所有网页,豆瓣业界良心啊。

7、运行结果