flower.py
# -*- coding: utf-8 -*-
import scrapy
from six_xiaohua.items import SixXiaohuaItem
#爬取大学生知识网的校花
#https://news.daxues.cn/xiaohua/ziliao/
class FlowerSpider(scrapy.Spider):
name = 'flower'
allowed_domains = ['daxues.cn']
start_urls = ['http://news.daxues.cn/xiaohua/ziliao/']
#定义一个成员变量,用于记录当前是第几页
page = 1
# 定义一个变量,记录通用url
page_url = 'https://news.daxues.cn/xiaohua/ziliao/index_'
def parse(self, response):
print("_______________________________________________")
flower_list = response.xpath("//div[@class='xh_list']/dl")
for flower in flower_list:
item = SixXiaohuaItem()
item["name"] = flower.xpath("./dt/a/text()").extract_first()
item["info"] = flower.xpath("./dd/text()").extract_first()
item["img_url"] = "http://news.daxues.cn" + flower.xpath("./a/img/@src").extract_first()
item["page_url"] = "http://news.daxues.cn" + flower.xpath("./a/@href").extract_first()
yield item
#给爬虫设置增量
#让当前页码加1
self.page += 1
#翻到下一页
if self.page <= 3:
#需要用下一页的url来重新调度下载器
#拼接下一页的url
url = self.page_url + str(self.page) + ".html"
#用yield调取下载器
yield scrapy.Request(url=url, callback=self.parse)
#Request这个类,是scrapy提供的用于get请求的下载器,url参数是要get的链接。callback是回调函数,在这需要传递一个函数的入口地址,当下载器把内容下载完毕后,就会调用这个callback函数,作用:把响应对象传入
items.py
import scrapy
class SixXiaohuaItem(scrapy.Item):
# define the fields for your item here like:
name = scrapy.Field()
info = scrapy.Field()
img_url = scrapy.Field()
page_url = scrapy.Field()
pipelines.py
# -*- coding: utf-8 -*-
# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: https://doc.scrapy.org/en/latest/topics/item-pipeline.html
import json
import csv
import pymysql
class SixXiaohuaPipeline(object):
#这个方法在下载器将开始下载并且交给蜘蛛来处理数据的时候调用
def open_spider(self, spider):
print("开始处理数据...")
#打开一个json文件
self.flower_items = open("flowers.json", "w", encoding="utf-8")
#定义一个列表,整个所有items的信息
self.items = []
# 打开一个csv文件
self.csvfile = open("flowers.csv", "w", encoding="utf-8")
#创建一个列表整个所有的csv数据
self.csvItems = []
print("开始处理数据...")
#这个成员方法每迭代一次下载结果,调用一次
def process_item(self, item, spider):
# print(item)
#把item转化为普通字典
dic = dict(item)
#追加到item列表
self.items.append(dic)
#整个csv数据,csv数据是一个二维列表,行和列的形式
csv_item = []
csv_item.append(item["name"])
csv_item.append(item["info"])
csv_item.append(item["img_url"])
csv_item.append(item["page_url"])
self.csvItems.append(csv_item)
return item
#所有数据在处理完毕之后,调用这个方法
def close_spider(self, spider):
#在这里把数据写入本地
self.flower_items.write(json.dumps(self.items))
#关掉,否则占内存
self.flower_items.close()
print('数据处理结束')
#将数据写入csv表格
#创建一个csv的写入对象
writor = csv.writer(self.csvfile) #这个writer就会向本地的csvfile文件中写入数据
#写表头
writor.writerow(["name", "info", "img_url", "page_url"])
#写内容
writor.writerows(self.csvItems)
print("数据处理结束!")
#定义一个类,用于操作mysql数据库
class MysqlPipeline(object):
# 初始化连接的相关参数
def __init__(self):
self.host = "127.0.0.1"
self.port = 3306
self.user = 'root'
self.password = '9998'
self.dbname = 'dxues'
def open_spider(self, spider):
#连接数据库
self.conn = pymysql.connect(
host=self.host,
port=self.port,
user=self.user,
password=self.password,
db=self.dbname,
charset="utf8",
)
#创建游标
self.cursor = self.conn.cursor()
def process_item(self, item, spider):
print("========================")
# 用游标执行sql语句
sql = "INSERT INTO flower VALUES (NULL,'%s','%s','%s','%s')" % (item["name"], item["info"], item["img_url"], item["page_url"])
self.cursor.execute(sql)
self.conn.commit()
return item
def close_spider(self, spider):
#关掉否则可能内存泄漏
self.conn.close()
self.cursor.close()
settings.py
ITEM_PIPELINES = {
'six_xiaohua.pipelines.SixXiaohuaPipeline': 300,
#开启数据库存储的管道
'six_xiaohua.pipelines.MysqlPipeline': 299,
}
网友评论