用Python Scrapy爬取某电影网站并存储入mysql

时间:2022-09-18 16:32:43

爬取目标:javlib,使用框架Scrapy



首先使用在命令行里

scrapy startproject projectname
scrapy genspider spidername
指令创建爬虫。

首先定义items.py

import scrapy


class AvmoItem(scrapy.Item):
    # define the fields for your item here like:
    name = scrapy.Field()
    pic = scrapy.Field()
    url = scrapy.Field()
    id_ = scrapy.Field()

这是spiders文件夹中的爬虫文件

spidername.py

# -*- coding: utf-8 -*-
import scrapy
import os
import sys
import re
import urllib.parse
sys.path.append(os.path.abspath(os.path.dirname(__file__) + '/' + '..'))
import items


class JavbusSpider(scrapy.Spider):
    name = 'javlibrary'
    allowed_domains = ['www.ja14b.com']
    start_urls = ['http://www.ja14b.com/cn/vl_genre.php?g=cu']

    # 爬取目录页
    def parse(self, response):
        # 通过xpath指令找到需要爬取的每部电影的url。
        for av in response.xpath("//div[@class=\"video\"]"):
            url = urllib.parse.urljoin('http://www.ja14b.com/cn/', av.xpath("a/@href").extract()[0])
            # 将每部电影的URL发送到parse_movie中进行下一步处理。
            yield scrapy.Request(url, callback=self.parse_movie)
        # 检查是否有下一页,如果有下一页,通过parse递归爬取下一页的内容
        next_page = response.xpath("//*[@class=\"page next\"]")
        if next_page:
            next_page_url = "http://www.ja14b.com" + response.xpath("//*[@id=\"rightcolumn\"]/div[3]/a[9]/@href").extract()[0]
            yield scrapy.Request(next_page_url, callback=self.parse)

    # 对每一部电影进行分析
    def parse_movie(self, response):
        title = response.xpath("//*[@id=\"video_title\"]/h3/a/text()").extract()[0]
        # 定义新的ITEM
        item = items.AvmoItem()
        # 通过regex获取*。
        id_ = re.search("[a-zA-Z]{2,5}-?\d{2,5}", title).group(0)
        name = title[len(id_)+1:]
        pic = "http:" + response.xpath("//*[@id=\"video_jacket_img\"]/@src").extract()[0]
        # 将每部电影的属性添加到item中。
        item["url"] = response.url
        item["id_"] = id_
        item["name"] = name
        item["pic"] = pic
        yield item

然后修改pipelines.py

# 通过pymysql连接电脑上的MySQL
import pymysql


class AvmoPipeline(object):
    def __init__(self):
        # 连接database
        self.db = pymysql.connect("localhost", "root", "6966xx511", "testDB", charset='utf8mb4', )
        # 通过cursor传达sql指令
        self.cursor = self.db.cursor()
        # 如果table存在,则drop,防止引发冲突。
        self.cursor.execute("DROP TABLE IF EXISTS AV")
        # 创建table av,以*(id)为primary key,防止重复。
        sql = """CREATE TABLE AV (
                         id  VARCHAR(255) NOT NULL,
                         name  VARCHAR(255),
                         pic  VARCHAR(255),
                         url VARCHAR(255),
                         magnet VARCHAR(255),
                         PRIMARY KEY (id)
                         );"""
        self.cursor.execute(sql)
        self.db.commit()

    def process_item(self, item, spider):
        # 每次收到一个item即将其加入table
        self.cursor.execute("ALTER TABLE AV CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;")
        sql = """INSERT INTO AV(id,name,pic,url)
                VALUES ('{}','{}','{}','{}');""".format(item['id_'], item['name'], item['pic'], item['url'])
        self.cursor.execute(sql)
        self.db.commit()
        return item

    def close_spider(self, spider):
        self.db.close()


这样,一个包含小电影的爬虫就成功了,注意如果Scrapy一直显示403error则需要手动修改settings.py,使ROBOTSTXT_OBEY = False。