一、项目背景与介绍
在当今的互联网时代,数据是企业最宝贵的资产之一。为了更好地利用这些数据,企业需要从各种来源收集、处理和存储数据。本项目旨在使用Python编程语言,通过Scrapy框架和Redis与MongoDB的结合,实现一个数据迁移和抓取系统。
二、项目目标
1. **数据迁移**:将存储在Redis中的数据迁移到MongoDB中。
2. **数据抓取**:使用Scrapy框架抓取网页数据,并存储到MongoDB。
三、技术栈
- **Python**:主要编程语言。
- **Scrapy**:一个快速的高级Web抓取和Web抓取框架。
- **Redis**:一个开源的内存数据结构存储系统。
- **MongoDB**:一个基于文档的NoSQL数据库。
- **PyMongo**:MongoDB的Python驱动程序。
- **redis-py**:Redis的Python客户端。
四、 整体思路
4.1 数据迁移
1. **连接Redis**:使用`redis-py`库连接到Redis服务器。
2. **读取数据**:从Redis中读取数据。
3. **转换数据**:将读取的数据转换为JSON格式。
4. **连接MongoDB**:使用`PyMongo`库连接到MongoDB服务器。
5. **存储数据**:将转换后的数据存储到MongoDB中。
4.2 数据抓取
1. **定义爬虫**:创建一个Scrapy爬虫,定义起始URL和允许的域。
2. **解析页面**:解析页面,提取URL并递归抓取。
3. **提取数据**:从页面中提取所需的数据。
4. **存储数据**:将提取的数据存储到MongoDB中。
4.3 部分重要代码讲解
### 数据迁移代码
```python
import json
import pymongo
import redis
def redis2mongo():
# 创建redis连接
r = redis.Redis(host='localhost', port=6379, db=0)
# 创建mongodb连接
m = pymongo.MongoClient('localhost', 27017)
# 创建mongodb的集合和文档
xiaoshuo = m.xs.content
while True:
# 读取redis数据
source, data = r.brpop(['xs.items'], timeout=2)
print(source, data)
# 将数据转换成json格式
r_data = json.load(data)
xiaoshuo.insert_one(r_data)
# 关闭数据连接
m.close()
r.close()
if __name__ == '__main__':
redis2mongo()
```
- **连接Redis和MongoDB**:使用`redis.Redis`和`pymongo.MongoClient`创建连接。
- **读取和存储数据**:使用`brpop`从Redis中读取数据,然后使用`insert_one`将数据存储到MongoDB中。
### 数据抓取代码
```python
import scrapy
class PinpaiSpider(scrapy.Spider):
name = "pinpai"
allowed_domains = ["chinapp.com"]
start_urls = ["https://www.chinapp.com/pinpai"]
def parse(self, response):
urls = response.xpath("//div[@class='hot-industry']/li/ul/li/a/@href").extract()
for url in urls:
complete_url = f"https://www.chinapp.com{url}"
yield scrapy.Request(complete_url, callback=self.parse_item)
def parse_item(self, response):
detail_urls = response.xpath('//ul[@class="pplb_items_lists"]/li/a/@href').extract()
for url in detail_urls:
complete_detail_url = f'https://www.chinapp.com{url}'
yield scrapy.Request(complete_detail_url, callback=self.parse_detail)
def parse_detail(self, response):
brand_name = response.xpath("//div[@class='brand_title']/h2/text()").get()
img_url = response.xpath("//div[@class='brand_pic']/img/@src").get()
company_name = response.xpath("//h4[@class='ellipsis']/text()").get()
items = response.xpath("//div[@class='items']/p[@class='c']/text()").extract()
legal_person = items[0] if len(items) > 0 else None
origin_place = items[1] if len(items) > 1 else None
establishment_time = items[2] if len(items) > 2 else None
phone = response.xpath("//div[@class='items']/p[@class='c mr_16']/text()").get()
official_website = response.xpath("//div[@class='items']/p[@class='c']/span/text()").get()
main_products = response.xpath("//div[@class='tag_list']/ul/li/text()").extract()
main_products_str = ','.join(main_products)
infos = response.xpath("//div[@class='item']/div[@class='n']/text()").extract()
likes = infos[0] if len(infos) > 0 else None
brand_info = infos[1] if len(infos) > 1 else None
comments = infos[2] if len(infos) > 2 else None
total_votes = infos[3] if len(infos) > 3 else None
yield {
"品牌名称": brand_name,
"LOGO图片地址": img_url,
"公司名称": company_name,
"法人代表": legal_person,
"发源地": origin_place,
"创立时间": establishment_time,
"品牌电话": phone,
"官网地址": official_website,
"主营产品": main_products_str,
"点赞数": likes,
"品牌资讯": brand_info,
"评论数": comments,
"总得票数": total_votes
}
```
- **定义爬虫**:创建一个名为`PinpaiSpider`的Scrapy爬虫。
- **解析页面**:使用`xpath`提取页面中的URL,并递归抓取。
- **提取数据**:从页面中提取品牌名称、LOGO图片地址、公司名称等信息。
五、 总结
本项目通过Python和Scrapy框架实现了数据的迁移和抓取。通过Redis和MongoDB的结合,实现了高效的数据存储和检索。Scrapy框架的使用大大提高了数据抓取的效率和灵活性。这个项目可以作为数据迁移和抓取任务的一个很好的参考。
六、未来展望
未来可以考虑将项目扩展到更多的数据源和目标数据库,以及增加更多的数据处理功能,如数据清洗、转换等。此外,还可以考虑使用更高级的爬虫技术,如IP代理、用户代理池等,以提高爬虫的稳定性和效率。