Django-Scrapy生成後端json接口

Django-Scrapy生成後端json接口:

網上的關於django-scrapy的介紹比較少,該博客只在本人查資料的過程當中學習的,若是不對之處,但願指出改正;html

之後的博客可能不會再出關於django相關的點;python

人心太浮躁,我的深度不夠,只學習了一些皮毛,後面博客只求精,不求多;mysql

但願能堅持下來。加油!git


學習點:

  1. 實現效果
  2. django與scrapy的建立
  3. setting中對接的位置和代碼段
  4. scrapy_djangoitem使用
  5. scrapy數據爬取保存部分
  6. 數據庫設計以及問題部分
  7. django配置

實現效果:

image-20201002162236215

django與scrapy的建立:

django的建立:github

django startproject 項目名稱
cd 項目名稱
python manage.py startapp appname

例如:sql

image-20201002141631912

scrapy的建立:數據庫

# cd django的根目錄下
cd job_hnting
scrapy startproject 項目名稱
#建立爬蟲
scrapy genspider spidername 'www.xxx.com'

例如:django

image-20201002142129066

setting的設置:

在scrapy框架中的setting指向django,讓django知道有scrapy;json

在scrapy中的setting設置;後端

import os
import django

#導入
os.environ['DJANGO_SETTINGS_MODULE'] = 'job_hnting.settings'
#手動初始化
django.setup()

如:

image-20201002143254407

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招聘網站的數據:

爬取分爲三個函數:

  1. 主函數
  2. 解析函數
  3. 總頁數函數

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

image-20200904181342156

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)

實現效果:

image-20201002162236215

完整代碼在GitHub中,但願隨手star,感謝!

若是有問題歡迎留言,平常在線。

相關文章
相關標籤/搜索