Scrapy 项目实战含翻页并存储MySql数据库以及下载图片
功能要求
爬取目标网址:https://www.photoworld.com.cn/
爬取文章(url,标题,标签,示例图片,作者,描述)。要求能翻页爬取。注意标签可能有多个。
查询功能:
1.按标题关键字查询,显示文章列表
2.按标签查询,显示文章列表
3.按作者查询,显示文章列表
在开始进行Scrapy项目实战前,应对Scrapy的基础概念有所了解。
当我们新建一个工程项目时,会有以下一些文件同时出现。在此对以解释。
Scrapy Engine(引擎) | Scrapy框架的核心部分。负责在Spider和ItemPipeline、Downloader、Scheduler中间通信、传递数据等。 |
---|---|
Spider(爬虫) | 发送需要爬取的链接给引擎,最后引擎把其他模块请求回来的数据再发送给爬虫,爬虫就去解析想要的数据。这个部分是我们开发者自己写的,因为要爬取哪些链接,页面中的哪些数据是我们需要的,都是由程序员自己决定。 |
Scheduler(调度器) | 负责接收引擎发送过来的请求,并按照一定的方式进行排列和整理,负责调度请求的顺序等。 |
Downloader(下载器) | 负责接收引擎传过来的下载请求,然后去网络上下载对应的数据再交还给引擎。 |
Item Pipeline(管道) | 负责将Spider(爬虫)传递过来的数据进行保存。具体保存在哪里,应该看开发者自己的需求。 |
Downloader Middlewares(下载中间件) | 可以扩展下载器和引擎之间通信功能的中间件。 |
Spider Middlewares(Spider中间件) | 可以扩展引擎和爬虫之间通信功能的中间件。 |
爬取步骤
首先新建自己的工程项目,先在D盘新建自己的项目文件夹,这里我的是D:\pycodes.
然后在Anaconda的Prompt(注意:进入自己的项目文件夹)输入scrapy startproject 项目名(pic)
接着创建一个spider:cd 项目名
scrapy genspider 爬虫名 “域名”
我的操作是scrapy genspider newspider “https://www.photoworld.com.cn/”
在项目下新建一个python文件,运行此文件即可运行爬虫项目,不需要再去命令行了
from scrapy import cmdline
cmdline.execute('scrapy crawl 爬虫名'.split())
准备阶段
在准备写爬虫文件之前,我们应该
首先在items.py中确定要爬取的字段
import scrapy
#from scrapy import Item,Field
#
class DemoItem(scrapy.Item):
# define the fields for your item here like:
# name = scrapy.Field()
title = scrapy.Field()
de = scrapy.Field()#描述
title_url = scrapy.Field()
time = scrapy.Field()
author = scrapy.Field()
new = scrapy.Field()
src = scrapy.Field()# 图片的url
tag = scrapy.Field()
pass
普通字段爬取
接下来开始写代码,在newspider.py中创建想要爬取的字段,首先应观察网页源码,通过xpath定位找到字段。
import scrapy
from demo.items import DemoItem
class ImgSpider(scrapy.Spider):
name ='img'
# allowed_domains = []
start_urls = ["https://www.photoworld.com.cn/page/1"]
# def start_requests(self): #翻页
# reqs =[]
# for i in range(1,5):
# url = 'https://www.photoworld.com.cn/page/'+str(i)
# req = scrapy.Request(url)
# reqs.append(req)
# return reqs
def parse(self, response):
articles = response.xpath('//div[@id="home-main"]//article[starts-with(@class,"single-thumb-article") or starts-with(@class,"triple-thumb-article") or starts-with(@class,"no-thumb-article")]')
# # print(articles)
image_urls = [] # 图片链接
for i in articles:
j = i.xpath(".//div[@class='thumbnail single-thumb-thumbnail tcell' or @class='thumbnail triple-thumb-thumbnail']")
if len(j)>0:
image_urls.append(' '.join(j[0].xpath('.//img/@src').extract()))
else:
image_urls