爬虫学习05

本文介绍了Python爬虫中CSV模块的使用,包括如何将爬取数据存储到CSV文件,以及猫眼电影Top100的抓取案例。此外,还详细讲解了如何利用pymysql模块将数据存入MySQL数据库,以及电影天堂网站的二级页面抓取方法,包括URL规律和正则表达式的应用。
摘要由CSDN通过智能技术生成

一、CSV模块

1.作用

将爬取的数据存到本地的CSV文件中

2.使用流程

1.导入模块

2.打开csv文件

3.初始化写入对象

4.写入数据(参数为列表)

import csv
with open('test.csv','w') as f:
     writer=csv.writer(f)
     #写一行
     writer.writerow(['小明',25])
     #写多行
     writer.writerow([(),(),(),()])

 windows中使用csv模块默认添加一个空行,使用newline=''可解决这个问题

3.示例代码

创建test.csv文件,在文件中写入2条数据(01_csv_example.py)

import csv

with open('test.csv','w',newline='') as f:
    # 初始化写入对象
    writer=csv.writer(f)
    writer.writerow(['易烊千玺',20])
    writer.writerow(['步惊云',22])

#追加数据
with open('test.csv','a',newline='') as f:
    writer=csv.writer(f)
    data_list=[('聂风',23),('秦霜',30)]
    writer.writerows(data_list)

二、猫眼电影top100抓取案例

1.确定url网址

2.目标

电影名称、主演、上映时间

3.操作步骤

(1)查看是否为动态加载

右键  ——查看网页源代码——搜索爬取关键字(查看在源代码中是否存在)

 (2)找url规律

第1页:https://www.maoyan.com/board/4?offset=0

第2页:https://www.maoyan.com/board/4?offset=10

第n页:offset=(n-1)*10

 (3)正则表达式

源代码:

 <div class="board-item-main">
      <div class="board-item-content">
              <div class="movie-item-info">
        <p class="name"><a href="/films/78341" title="星际穿越" data-act="boarditem-click" data-val="{movieId:78341}">星际穿越</a></p>
        <p class="star">
                主演:马修·麦康纳,安妮•海瑟薇,杰西卡·查斯坦
        </p>
<p class="releasetime">上映时间:2014-11-12</p>    </div>

 正则表达式

<div class="movie-item-info">.*?title="(.*?)".*?class="star">(.*?)</p>.*?releasetime">(.*?)</p>

 猫眼之前的版本,不需要滑块验证

import random
import urllib
from  urllib import request
import time
import re
import csv

class MaoyanSpider(object):

    def __init__(self):
        self.url='https://maoyan.com/board/4?offset={}'
        self.user_agent_list=[
            'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:34.0) Gecko/20100101 Firefox/34.0 ',
            'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.101 Safari/537.36 ',
            'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; QQDownload 732; .NET4.0C; .NET4.0E)',
            'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; en) Opera 9.50']

    #获取数据
    def get_page(self,url):
        # 每次使用随机的user - agent
        headers = {'User-Agent':random.choice(self.user_agent_list)}
        request=urllib.request.Request(
            url=url,
            headers=headers
        )
        response=urllib.request.urlopen(request)
        html=response.read().decode('utf-8')
        #调用解析函数
        self.parse_page(html)

    #解析数据
    def parse_page(self,html):
        pattern=re.compile('<div class="movie-item-info">.*?title="(.*?)".*?class="star">(.*?)</p>.*?releasetime">(.*?)</p>',re.S)
        r_list=pattern.findall(html)
        self.write_page(r_list)

    #保存数据
    def write_page(self,r_list):
        one_film_dict={}
        for rt in r_list:
            one_film_dict['name']=rt[0].strip()
            one_film_dict['star']=rt[1].strip()
            one_film_dict['time']=rt[2].strip()

            print(one_film_dict)



    #主函数
    def main(self):
        for offset in range(0,91,10):
            url=self.url.format(offset)
            self.get_page(url)
            time.sleep(random.randint(1,3))



if __name__=='__main__':
    start=time.time()
    spider=MaoyanSpider()
    spider.main()
    end=time.time()
    print('执行时间:%.2f' % (end-start))

结果展示 

 

 现在的版本,需要验证

# encoding=utf-8
import random
import urllib
from urllib import request
import time
import re
import csv

import requests


class MaoyanSpider(object):

    def __init__(self):
        self.url = 'https://maoyan.com/board/4?offset={}'
        self.user_agent_list = [
            'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:34.0) Gecko/20100101 Firefox/34.0 ',
            'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.101 Safari/537.36 ',
            'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; QQDownload 732; .NET4.0C; .NET4.0E)',
            'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; en) Opera 9.50'
        ]

    # 获取数据
    def get_page(self, url):
        # 每次使用随机的user - agent
        headers = {
            'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
            'Accept-Language': 'zh-CN,zh;q=0.9',
            'Connection': 'keep-alive',
            # 'Referer': 'https://www.maoyan.com/',
            'Sec-Fetch-Dest': 'document',
            'Sec-Fetch-Mode': 'navigate',
            'Sec-Fetch-Site': 'same-origin',
            'Sec-Fetch-User': '?1',
            'Upgrade-Insecure-Requests': '1',
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.67 Safari/537.36',
            'sec-ch-ua': '" Not A;Brand";v="99", "Chromium";v="101", "Google Chrome";v="101"',
            'sec-ch-ua-mobile': '?0',
            'sec-ch-ua-platform': '"Windows"',
        }
        response = requests.get(url=url, headers=headers)
        # 调用解析函数
        self.parse_page(response.text)

    # 解析数据
    def parse_page(self, html):
        pattern = re.compile(
            '<div class="movie-item-info">.*?title="(.*?)".*?class="star">(.*?)</p>.*?releasetime">(.*?)</p>', re.S)
        r_list = pattern.findall(html)
        self.write_page(r_list)

    # 保存数据
    def write_page(self, r_list):
        one_film_dict = {}
        for rt in r_list:
            one_film_dict['name'] = rt[0].strip()
            one_film_dict['star'] = rt[1].strip()
            one_film_dict['time'] = rt[2].strip()
            print(one_film_dict)

#保存数据,存入csv
#    def write_page(self, r_list):
        # 打开文件要在for循环之前
#        with open('maoyan.csv', 'a') as f:
  #          for rt in r_list:
  #              writer = csv.writer(f)
  #              writer.writerow(
   #                 [rt[0], rt[1].strip(), rt[2].strip()[5, 15]]
   #             )


    # 主函数
    def main(self):
        for offset in range(0, 91, 10):
            # url = self.url.format(offset)
            url = 'https://www.maoyan.com/board/4?timeStamp=1652929876901&channelId=40011&index=6&signKey=3a37c66f9ad17859383d8d4f02708497&sVersion=1&webdriver=false&offset={}'.format(
                offset)
            self.get_page(url)
            time.sleep(random.randint(1, 3))
            print('第%页爬取完成'%self.page)
            self.page += 1



if __name__ == '__main__':
    start = time.time()
    spider = MaoyanSpider()
    spider.main()
    end = time.time()
    print('执行时间:%.2f' % (end - start))

结果展示

三、数据持久化(mysql数据库)

1.pymysql模块

(1)execute()

import pymysql

#数据库连接对象
db=pymysql.connect(
    host='127.0.0.1',#连接名称
    user='root',#用户名
    password='0000',  # 密码
    db='spider',#数据库名称
    charset='utf8'
)
#游标对象
cursor=db.cursor()

#execute()方法第二个参数为列表传参补位
cursor.execute('insert into film values(%s,%s,%s)',
['霸王别姬','张国荣','1993'])

#提交到数据库执行
db.commit()

#关闭
cursor.close()
db.close()

(2)executemany

import pymysql

#数据库连接对象
db=pymysql.connect(
    host='127.0.0.1',#连接名称
    user='root',#用户名
    password='0000',  # 密码
    db='spider',#数据库名称
    charset='utf8'
)
#游标对象
cursor=db.cursor()

#存放所有数据的大列表
ins_list=[]
for i in range(2):
    name=input('请输入第%d个学生姓名:'%(i+1))
    age=input('请输入第%d个学生年龄:'%(i+1))
    ins_list.append([name,age])
    #定义插入语句
    ins='insert into t3 values(%s,%s)'
    #一次数据库的IQ操作可插入多条语句,提升功能
    cursor.executemany(ins,ins_list[[],[],[]])

#提交到数据库执行
db.commit()
#关闭
cursor.close()
db.close()

 (3)存入到mysql数据库

import random
import urllib
from  urllib import request
import time
import re
import csv

import pymysql


class MaoyanSpider(object):

    def __init__(self):
        self.url='https://maoyan.com/board/4?offset={}'
        self.user_agent_list=[
            'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:34.0) Gecko/20100101 Firefox/34.0 ',
            'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.101 Safari/537.36 ',
            'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; QQDownload 732; .NET4.0C; .NET4.0E)',
            'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; en) Opera 9.50']
        #用于记录页数
        self.page=1
        #创建数据库连接对象和游标对象
        # 数据库连接对象
        self.db = pymysql.connect(
            host='127.0.0.1',  # 连接名称
            user='root',  # 用户名
            password='0000',  # 密码
            db='spider',  # 数据库名称
            charset='utf8'
        )
        # 游标对象
        cursor = self.db.cursor()

    #获取数据
    def get_page(self,url):
        # 每次使用随机的user - agent
        headers = {'User-Agent':random.choice(self.user_agent_list)}
        request=urllib.request.Request(
            url=url,
            headers=headers
        )
        response=urllib.request.urlopen(request)
        html=response.read().decode('utf-8')
        #调用解析函数
        self.parse_page(html)

    #解析数据
    def parse_page(self,html):
        pattern=re.compile('<div class="movie-item-info">.*?title="(.*?)".*?class="star">(.*?)</p>.*?releasetime">(.*?)</p>',re.S)
        r_list=pattern.findall(html)
        self.write_page(r_list)

    #保存数据,打印输出
#    def write_page(self,r_list):
#       one_film_dict={}
#       for rt in r_list:
#           one_film_dict['name']=rt[0].strip()
#           one_film_dict['star']=rt[1].strip()
#          one_film_dict['time']=rt[2].strip()
#           print(one_film_dict)

#存入mysql数据库(executemany()[[],[],[],[]])
    def write_page(self, r_list):
       #定义空列表v
        film_list={}
        ins='insert into film values(%s,%s,%s)'
        #处理数据,放到大列表film_list中
        for rt in r_list:
            one_film=[
                rt[0],rt[1].strip(),rt[2].strip()[5:15 ]
            ]
            #添加到大列表中
            film_list.append(one_film)
            #一次数据库的IO把1页数据存入
            self.cursor.executemany(ins,film_list)
            #提交列表数据库执行
            self.db.commit()


    #主函数
    def main(self):
        for offset in range(0,31,10):
            url=self.url.format(offset)
            self.get_page(url)
            time.sleep(random.randint(1,3))
            print('第%页爬取完成'%self.page)
            self.page += 1

        #所有页爬完之后再断开
        self.cursor.close()
        self.db.close()


if __name__=='__main__':
    start=time.time()
    spider=MaoyanSpider()
    spider.main()
    end=time.time()
    print('执行时间:%.2f' % (end-start))

三、电影天堂案例(二级页面抓取)

1.查看是否为静态页面

右键---查看网页源代码

2. 确定url地址

百度搜索:电影天堂-2022最新电影-更多

3. 目标

一级页面

  • 电影名称
  • 电影链接

二级页面

  • 下载链接

4.步骤

(1)找URL规律

第一页
https://www.ygdy8.net/html/gndy/dyzz/list_23_1.html

第二页

https://www.ygdy8.net/html/gndy/dyzz/list_23_2.html

第n页

https://www.ygdy8.net/html/gndy/dyzz/list_23_n.html

(2)写正则表达式

一级页面正则表达式(电影名称、电影详情链接)

<table width="100%".*?<td height="26">.*?<a href="(.*?)">.*?>(.*?)</a>   

二级页面正则表达式

<td style="WORD-WRAP.*?>.*?>(.*?)</a>

 代码演示

import urllib
from urllib import request
import re
import time
import random

import pymysql
from pymysql import connect

class FilmSky(object):
    def __init__(self):
        self.url='https://www.ygdy8.net/html/gndy/dyzz/list_23_{}.html'
        self.user_agent_list = [
            'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:34.0) Gecko/20100101 Firefox/34.0 ',
            'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.101 Safari/537.36 ',
            'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; QQDownload 732; .NET4.0C; .NET4.0E)',
            'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; en) Opera 9.50']
        #定义两个对象
        self.db = pymysql.connect(
            host='127.0.0.1',  # 连接名称
            user='root',  # 用户名
            password='0000',  # 密码
            db='spider',  # 数据库名称
            charset='utf8'
        )
        # 游标对象
        self.cursor = self.db.cursor()


    #获取html函数(因为两个页面都需要发请求)
    def get_page(self,url):
        headers = {'User-Agent': random.choice(self.user_agent_list)}
        request = urllib.request.Request(
            url=url,
            headers=headers
        )
        response=urllib.request.urlopen(request)
        #ignore参数,实在处理不了的编码错误忽略
        #查看网页源码,发现网页编码为gb2312,不是utf-8
        html=response.read().decode('gbk','ignore')
        return html

    #解析提取数据(把名称和下载链接一次性拿到)
    #html为一级响应页面的内容
    def parse_page(self,html):
        #先解析一级页面(电影名称和详情链接)
        pattern=re.compile('<table width="100%".*?<td height="26">.*?<a href="(.*?)".*?>(.*?)</a>',re.S)
        #film_list:[('详情链接',‘名称’),()]
        film_list=pattern.findall(html)
        ins='insert into sky_film values(%s,%s)'
        #print(film_list)
        for film in film_list:
            film_name=film[1]
            film_link='https://www.ygdy8.net'+film[0]

        #拿到详情链接后,再获取详情链接html,提取下载链接
            download_link=self.parse_two_html(film_link)

            self.cursor.execute(ins,[film_name,film_link])
            # 提交列表数据库执行
            self.db.commit()
        #打印测试
            d={
            '电影名称':film_name,
            '下载链接':download_link
            }
            print(d)
    #解析二级页面,获取下载链接
    def parse_two_html(self,film_link):
        two_html=self.get_page(film_link)
        pattern=re.compile('<td colspan="2".*?<a target="_blank" href="(.*?)">',re.S)
        download_link=pattern.findall(two_html)[0]

        return download_link


    #主函数
    def main(self):
        for page in range(1,3):
            url=self.url.format(page)
            html=self.get_page(url)
            self.parse_page(html)
            time.sleep(random.randint(1,3))
            print('第%d页完成'%page)
            # 所有页爬完之后再断开
        self.cursor.close()
        self.db.close()


if __name__=='__main__':
    start=time.time()
    spider=FilmSky()
    spider.main()
    end=time.time()
    print('执行时间:%.2f'%(end-start))


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值