前言
- 蛋肥学习了Scrapy框架,打算实践一下,利用Scrapy来爬取一下最美应用推荐APP的数据,并储存到MySQL数据库中。
准备
爬取时间:2021/02/04
系统环境:Windows 10
所用工具:Jupyter Notebook\Python 3.0
涉及的库:scrapy\requests\json\lxml\pymysql
获取基础数据
最美应用
http://zuimeia.com/apps/?page=1&platform=2
参考资料
scrapy保存到mysql数据库
小提示
scrapy的多线程机制导致抓回来的数据是无序的。
创建项目
#cmd里依次执行代码,创建scrapy项目
cd C:\Users\Archer\Desktop
scrapy startproject appSpider
定义目标字段
#对项目文件夹里的items.py做以下修改
import scrapy
class appspiderItem(scrapy.Item):
app_name = scrapy.Field() #名称
app_intro = scrapy.Field() #描述
app_like = scrapy.Field() #喜爱数
app_time = scrapy.Field() #发布时间
app_link = scrapy.Field() #详情链接
app_content = scrapy.Field() #推荐内容
创建爬虫器
#cmd里依次执行代码,创建爬虫器
cd C:\Users\Archer\Desktop\appSpider
scrapy genspider app zuimeia.com
修改爬虫器
#对项目文件夹里的app.py做以下修改
import scrapy
import requests
import json
from lxml import etree
from appSpider.items import appspiderItem
class AppSpider(scrapy.Spider):
name = 'app'
allowed_domains = ['zuimeia.com']
start_urls = ['http://zuimeia.com/apps/?page=1&platform=2']
headers={"User-Agent":"Mozilla/5.0 (Windows NT 10.0; WOW64; rv:43.0) Gecko/20100101 Firefox/43.0"}
url_head="http://zuimeia.com/apps/?page="
url_end="&platform=2"
#从start_requests开始发送请求
def start_requests(self):
for i in range(1,11):
url=self.url_head+str(i)+self.url_end
yield scrapy.Request(url=url,callback=self.parse, headers=self.headers)
#获取推荐页面的相关数据
def parse(self, response):
html=etree.HTML(response.text)
app_name=html.xpath('//a[@class="app-title"]/h1/text()')
app_intro=html.xpath('//a[@class="quote-text"]/text()')
app_time=html.xpath('//span[@class="pub-time"]/text()')
app_link=html.xpath('//a[@class="app-title"]/@href')
#因喜爱数是动态加载的,通过Network找到实际url,单独进行解析
app_id=html.xpath('//a[@class="app-title"]/@data')
app_like=[]
for i in range(len(app_id)):
like_link="http://zuimeia.com/apps/up/?ids="+str(app_id[i])
r=requests.get(like_link,headers=self.headers,timeout=10)
json_string=r.text
json_data=json.loads(json_string)
like=json_data["data"][0].get(str(app_id[i]))
app_like.append(like)
#将数据封装到appspiderItem
for i in range(len(app_name)):
item=appspiderItem()
item["app_name"]=app_name[i]
item["app_intro"]=app_intro[i]
item["app_time"]=app_time[i]
item["app_link"]=app_link[i]
item["app_like"]=app_like[i]
yield scrapy.Request(url="http://zuimeia.com"+app_link[i],meta={"item":item},callback=self.parse2)
def parse2(self, response):
item=response.meta["item"]
#提取内容
html=etree.HTML(response.text)
text=html.xpath('//*[@id="article_content"]/p/text()')
app_content=""
for i in range(len(text)):
app_content=app_content+text[i]
item["app_content"]=app_content
yield item
创建数据库
#在Workbench里创建数据库
CREATE DATABASE app;
USE app;
CREATE TABLE zuimeiapp(
id INT NOT NULL AUTO_INCREMENT,
app_name VARCHAR(50) NOT NULL,
app_intro VARCHAR(500) NOT NULL,
app_like VARCHAR(50) NOT NULL,
app_time VARCHAR(50) NOT NULL,
app_link VARCHAR(100) NOT NULL,
app_content VARCHAR(5000) NOT NULL,
created_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY(id)
);
修改存储文件
#对项目文件夹里的pipelines.py做以下修改,因数据量较少,用同步操作
from itemadapter import ItemAdapter
import pymysql
class AppspiderPipeline():
def __init__(self):
#打开数据库链接
self.conn=pymysql.connect("localhost","root","password","app",charset='utf8')
#获取操作游标
self.cursor=self.conn.cursor()
def process_item(self,item,spider):
#SQL插入语句
sql="""INSERT INTO zuimeiapp(app_name,app_intro,app_like,app_time,app_link,app_content) VALUES(%s,%s,%s,%s,%s,%s);"""
try:
#执行语句
self.cursor.execute(sql,(item["app_name"],item["app_intro"],item["app_like"],item["app_time"],item["app_link"],item["app_content"]))
#提交到数据库执行
self.conn.commit()
except:
#如果出错就回滚
self.conn.rollback()
def close_spider(self,spider):
#关闭数据库
self.cursor.close()
self.conn.close()
修改设置文件
#对项目文件夹里的settings.py以下内容取消注释
ITEM_PIPELINES = {
'appSpider.pipelines.AppspiderPipeline': 300,
}
运行爬虫
#cmd里依次执行代码,运行爬虫
cd C:\Users\Archer\Desktop\appSpider
scrapy crawl app
大功告成
总结
- scrapy的多线程机制可使抓取速度变快。
- 根据数据量的多少,可以选择同步或异步操作将数据写入数据库。