Django-Scrapy生成後端json介面:
網上的關於django-scrapy的介紹比較少,該部落格只在本人查資料的過程中學習的,如果不對之處,希望指出改正;
以後的部落格可能不會再出關於django相關的點;
人心太浮躁,個人深度不夠,只學習了一些皮毛,後面部落格只求精,不求多;
希望能堅持下來。加油!
學習點:
- 實現效果
- django與scrapy的建立
- setting中對接的位置和程式碼段
- scrapy_djangoitem使用
- scrapy資料爬取儲存部分
- 資料庫設計以及問題部分
- django配置
實現效果:
django與scrapy的建立:
django的建立:
django startproject 專案名稱
cd 專案名稱
python manage.py startapp appname
例如:
scrapy的建立:
# cd django的根目錄下
cd job_hnting
scrapy startproject 專案名稱
#建立爬蟲
scrapy genspider spidername 'www.xxx.com'
例如:
setting的設定:
在scrapy框架中的setting指向django,讓django知道有scrapy;
在scrapy中的setting設定;
import os
import django
#匯入
os.environ['DJANGO_SETTINGS_MODULE'] = 'job_hnting.settings'
#手動初始化
django.setup()
如:
scrapy_djangoitem使用:
pip install scrapy_djangoitem
該庫在scrapy專案下的item中編寫引入:
import scrapy
# 引入django中app中models檔案中的類
from app51.models import app51data
# scrapy與django對接的庫
from scrapy_djangoitem import DjangoItem
class JobprojectItem(DjangoItem):
#引用django下的model中的類名
django_model = app51data
資料儲存部分對接在後面解釋,現在大體框架完整;
scrapy爬取儲存部分:
首先編寫scrapy爬蟲部分:
我們選取的是51招聘網站的資料:
爬取分為三個函式:
- 主函式
- 解析函式
- 總頁數函式
51job的反爬手段:
將json的資料格式隱藏在網頁結構中,網上教程需要別的庫解析(自行了解),
我們的方法是使用正則匹配提取定位到資料部分,使用json庫解析:
# 定位資料位置,提取json資料
search_pattern = "window.__SEARCH_RESULT__ = (.*?)</script>"
jsonText = re.search(search_pattern, response.text, re.M | re.S).group(1)
獲得關鍵字總頁數:
# 解析json資料
jsonObject = json.loads(jsonText)
number = jsonObject['total_page']
在主函式中構造頁面url並給到解析函式:
for number in range(1,int(numbers)+1):
next_page_url = self.url.format(self.name,number)
# print(next_page_url)
#構造的Urlcallback到data_parse函式中
yield scrapy.Request(url=next_page_url,callback=self.data_parse)
最後在解析函式中提取需要的資料:
for job_item in jsonObject["engine_search_result"]:
items = JobprojectItem()
items['job_name'] = job_item['job_name']
items['company_name'] = job_item["company_name"]
# 釋出時間
items['Releasetime'] = job_item['issuedate']
items['salary'] = job_item['providesalary_text']
items['site'] = job_item['workarea_text']
.......
相關的細節部分需要自己調整,完整程式碼在GitHub中。
資料爬取部分解決後,需要到scrapy專案中的pipline檔案儲存;
class SeemeispiderPipeline(object):
def process_item(self, item, spider):
item.save()
return item
記得在setting檔案中取消掉pipline的註釋
設定資料庫:
Django配置資料庫有兩種方法:
方法一:直接在settings.py檔案中新增資料庫配置資訊(個人使用的)
DATABASES = {
# 方法一
'default': {
'ENGINE': 'django.db.backends.mysql', # 資料庫引擎
'NAME': 'mysite', # 資料庫名稱
'USER': 'root', # 資料庫登入使用者名稱
'PASSWORD': '123', # 密碼
'HOST': '127.0.0.1', # 資料庫主機IP,如保持預設,則為127.0.0.1
'PORT': 3306, # 資料庫埠號,如保持預設,則為3306
}
}
方法二:將資料庫配置資訊存到一個檔案中,在settings.py檔案中將其引入。
新建資料庫配置檔案my.cnf(名字隨意選擇)
[client]
database = blog
user = blog
password = blog
host =127.0.0.1
port = 3306
default-character-set = utf8
在settings.py檔案中引入my.cnf檔案
DATABASES = {
# 方法二:
'default': {
'ENGINE': 'django.db.backends.mysql',
'OPTIONS': {
'read_default_file': 'utils/dbs/my.cnf',
},
}
}
啟用Django與mysql的連線
在生產環境中安裝pymysql並且需要在settings.py檔案所在包中的__init__.py
中匯入pymysql
import pymysql
pymysql.install_as_MySQLdb()
對應前面的item,在spider中編寫時按照model設定的即可;;
from django.db import models
# Create your models here.
#定義app51的資料模型
class app51data(models.Model):
#釋出時間,長度20
Releasetime = models.CharField(max_length=20)
#職位名,長度50
job_name =models.CharField(max_length=50)
#薪水
salary = models.CharField(max_length=20)
#工作地點
site = models.CharField(max_length=50)
#學歷水平
education = models.CharField(max_length=20)
#公司名稱
company_name = models.CharField(max_length=50)
#工作經驗
Workexperience = models.CharField(max_length=20)
#指定表名
class Meta:
db_table = 'jobsql51'
def __str__(self):
return self.job_name
當指定完表名後,在DBMS中只需要建立對應的資料庫即可,表名自動建立
每次修改資料庫都要進行以下命令:
python manage.py makemigrations
python manage.py migrate
到此mysql資料庫配置完成
配置資料庫時遇到的錯誤:
Django啟動報錯:AttributeError: 'str' object has no attribute 'decode'
解決方法:
找到Django安裝目錄
G:\env\django_job\Lib\site-packages\django\db\backends\mysql\operations.py
編輯operations.py;
將146行的decode修改成encode
def last_executed_query(self, cursor, sql, params):
# With MySQLdb, cursor objects have an (undocumented) "_executed"
# attribute where the exact query sent to the database is saved.
# See MySQLdb/cursors.py in the source distribution.
query = getattr(cursor, '_executed', None)
if query is not None:
#query = query.decode(errors='replace')
uery = query.encode(errors='replace')
return query
django配置:
關於django的基礎配置,如路由,app的註冊等基礎用法,暫時不過多說明;
以下主要關於APP中檢視的配置,生成json;
from django.shortcuts import render
from django.http import HttpResponse
# Create your views here.
#引入資料
from .models import app51data
import json
def index(request):
# return HttpResponse("hello world")
# return render(request,'index.html')
#獲取所有的物件,轉換成json格式
data =app51data.objects.all()
list3 = []
i = 1
for var in data:
data = {}
data['id'] = i
data['Releasetime'] = var.Releasetime
data['job_name'] = var.job_name
data['salary'] = var.salary
data['site'] = var.site
data['education'] = var.education
data['company_name'] = var.company_name
data['Workexperience'] = var.Workexperience
list3.append(data)
i += 1
# a = json.dumps(data)
# b = json.dumps(list2)
# 將集合或字典轉換成json 物件
c = json.dumps(list3)
return HttpResponse(c)
實現效果:
完整程式碼在GitHub中,希望隨手star,感謝!
如果有問題歡迎留言,日常線上。