python利用xpath爬取网上数据并存储到django模型中

帮朋友制作一个网站,需要一些产品数据信息,因为是代理其他公司产品,直接爬取代理公司产品数据

1.设计数据库

from django.db import models
from uuslug import slugify
import uuid
import os

def products_directory_path(instance, filename):
  ext = filename.split('.')[-1]
  filename = '{}.{}'.format(uuid.uuid4().hex[:8], ext)
  # return the whole path to the file
  return os.path.join('images', "products", instance.title, filename)

def product_relatedimage_directory_path(instance, filename):
  ext = filename.split('.')[-1]
  filename = '{}.{}'.format(uuid.uuid4().hex[:8], ext)
  # return the whole path to the file
  return os.path.join('images', "product_relatedimage", instance.product.title, filename)

class ProductsCategory(models.Model):
  """产品分类"""
  name = models.CharField('产品分类名', max_length=80, unique=True)
  description = models.TextField('产品分类描述', blank=True, null=True)
  slug = models.SlugField('slug', max_length=80, blank=True, null=True)
  parent_category = models.ForeignKey('self', verbose_name="父级分类", blank=True, null=True, on_delete=models.CASCADE)

  def save(self, *args, **kwargs):
    if not self.id or not self.slug:
      self.slug = slugify(self.name)
    super().save(*args, **kwargs)

  def __str__(self):
    return self.name

  class Meta:
    ordering = ['name']
    verbose_name = "产品分类"
    verbose_name_plural = verbose_name

class ProductsTag(models.Model):
  """产品标签"""
  name = models.CharField('产品标签名', max_length=30, unique=True)
  slug = models.SlugField('slug', max_length=40)

  def __str__(self):
    return self.name

  def save(self, *args, **kwargs):
    if not self.id or not self.slug:
      self.slug = slugify(self.name)
    super().save(*args, **kwargs)

  class Meta:
    ordering = ['name']
    verbose_name = "产品标签"
    verbose_name_plural = verbose_name

class Product(models.Model):
  title = models.CharField('标题', max_length=255, unique=True)
  slug = models.SlugField('slug', max_length=255, blank=True, null=True)
  jscs = models.TextField('技术参数', blank=True, null=True)
  image = models.ImageField(upload_to=products_directory_path, verbose_name="产品图片")
  views = models.PositiveIntegerField('浏览量', default=0)
  category = models.ForeignKey('ProductsCategory', verbose_name='分类', on_delete=models.CASCADE, blank=True, null=True)
  tags = models.ManyToManyField('ProductsTag', verbose_name='标签集合', blank=True)

  def save(self, *args, **kwargs):
    if not self.id or not self.slug:
      self.slug = slugify(self.title)
    super().save(*args, **kwargs)

  def update_views(self):
    self.views += 1
    self.save(update_fields=['views'])

  def get_pre(self):
    return Product.objects.filter(id__lt=self.id).order_by('-id').first()

  def get_next(self):
    return Product.objects.filter(id__gt=self.id).order_by('id').first()

  def __str__(self):
    return self.title

  class Meta:
    verbose_name = "产品"
    verbose_name_plural = verbose_name

class ProductAdvantage(models.Model):
  content = models.TextField('产品优势', blank=True, null=True)
  product = models.ForeignKey(Product, on_delete=models.CASCADE, blank=True, null=True)

  def __str__(self):
    return self.content

  class Meta:
    verbose_name = "产品优势"
    verbose_name_plural = verbose_name

class ProductBody(models.Model):
  body = models.CharField('产品内容', max_length=256, blank=True, null=True)
  product = models.ForeignKey(Product, on_delete=models.CASCADE, blank=True, null=True)

  def __str__(self):
    return self.product.title

  class Meta:
    verbose_name = "产品内容"
    verbose_name_plural = verbose_name

2.脚本编写

2.1编写获取网页源代码函数

def get_one_page(url):
  try:
    headers = {
      "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36"}
    res = requests.get(url=url, headers=headers)
    res.encoding = 'utf-8'
    if res.status_code == 200:
      return res.text
    else:
      return None
  except Exception:
    return None

2.2根据base页面获取所有产品分类页面链接

if __name__ == '__main__':
  content = get_one_page(url)
  tree = etree.HTML(content)
  # 产品分类url
  catgory_urls = tree.xpath('//div[@class="fdh-01-nav"]/div/h3/a/@href')
  # 处理catgory_urls
  for url in catgory_urls:
    url = 'http://www.kexinjianji.com' + url
    print(url)

2.3根据产品分类页面链接获取对应所有产品链接

if __name__ == '__main__':
  content = get_one_page(url)
  tree = etree.HTML(content)
  # 产品分类
  catgory = tree.xpath('//div[@class="cplb-3n-ts-03 b"]/h3/span/text()')
  print("产品分类:" + catgory[0])
  # 该分类下产品url
  urls = tree.xpath('//div[@class="cplb-3n-ts-03-list"]/dl/dt/a/@href')
  # 处理url
  for url in urls:
    url = 'http://www.kexinjianji.com' + url
    print(url)
  print("=====================================================")

两者结合起来就可以打印出所有产品链接

if __name__ == '__main__':
  content = get_one_page(url)
  tree = etree.HTML(content)
  # 产品分类url
  catgory_urls = tree.xpath('//div[@class="fdh-01-nav"]/div/h3/a/@href')
  # 处理catgory_urls
  for url in catgory_urls:
    url = 'http://www.kexinjianji.com' + url
    content = get_one_page(url)
    tree = etree.HTML(content)
    # 产品分类
    catgory = tree.xpath('//div[@class="cplb-3n-ts-03 b"]/h3/span/text()')
    print("产品分类:" + catgory[0])
    # 该分类下产品url
    urls = tree.xpath('//div[@class="cplb-3n-ts-03-list"]/dl/dt/a/@href')
    # 处理url
    for url in urls:
      url = 'http://www.kexinjianji.com' + url
      print(url)
    print("=====================================================")

2.2使用xpath解析函数返回产品链接的内容

if __name__ == '__main__':
  content = get_one_page(url)
  tree = etree.HTML(content)
  # 产品名称
  title = tree.xpath('//*[@id="wrap"]//h1/text()')
  images = tree.xpath('//div[@class="sol_tj_left"]/a/img/@src')
  # 产品图片
  images_url = 'http://www.kexinjianji.com/' + images[0]
  # 性能特点
  xntd = tree.xpath('//div[@class="w"]//div/span/text()|//div[@class="w"]//div/text()')
  # 技术参数
  jscs = tree.xpath('//table')[0]
  jscs_str = etree.tostring(jscs, encoding='utf-8').decode('utf-8')
  # 产品内容
  cpnr = tree.xpath('//div[@class="describe"]/p')
  print('产品名称:' + title[0])
  print('产品图片:' + images_url)
  for td in xntd:
    print('性能特点:' + td)
  print('技术参数:' + jscs_str)
  for cp in cpnr:
    # string(.) 获取当前标签下所有文本内容
    cp = cp.xpath('string(.)')
    print('产品内容:' + cp)
  print('============================================')

将三者结合在一起就可以获取所有产品信息

if __name__ == '__main__':
  content = get_one_page(url)
  tree = etree.HTML(content)
  # 产品分类url
  catgory_urls = tree.xpath('//div[@class="fdh-01-nav"]/div/h3/a/@href')
  # 处理catgory_urls
  for url in catgory_urls:
    url = 'http://www.kexinjianji.com' + url
    content = get_one_page(url)
    tree = etree.HTML(content)
    # 产品分类
    catgory = tree.xpath('//div[@class="cplb-3n-ts-03 b"]/h3/span/text()')
    # 该分类下产品url
    urls = tree.xpath('//div[@class="cplb-3n-ts-03-list"]/dl/dt/a/@href')
    # 处理url
    for url in urls:
      url = 'http://www.kexinjianji.com' + url
      content = get_one_page(url)
      try:
        tree = etree.HTML(content)
        # 产品名称
        title = tree.xpath('//*[@id="wrap"]//h1/text()')
        images = tree.xpath('//div[@class="sol_tj_left"]/a/img/@src')
        # 产品图片
        images_url = 'http://www.kexinjianji.com' + images[0]
        # 性能特点
        xntd = tree.xpath('//div[@class="w"]//div/span/text()|//div[@class="w"]//div/text()')
        # 技术参数
        jscs = tree.xpath('//table')[0]
        jscs_str = etree.tostring(jscs, encoding='utf-8').decode('utf-8')
        # 产品内容
        cpnr = tree.xpath('//div[@class="describe"]/p')
        print("产品分类:" + catgory[0])
        print('产品链接:' + url)
        print('产品名称:' + title[0])
        print('产品图片:' + images_url)
        for td in xntd:
          print('性能特点:' + td.strip())
        # print('技术参数:' + jscs_str)
        for cp in cpnr:
          # string(.) 获取当前标签下所有文本内容
          cp = cp.xpath('string(.)')
          print('产品内容:' + cp)
        print('============================================')
      except Exception as e:
        print(e)
        print('出错url:' + url)
        pass

3.存储到django模型

import requests
from lxml.html import etree
import os
import django
import uuid
from django.core.files.base import ContentFile

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "jiaobanzhan.settings")
django.setup()

from products.models import ProductBody, ProductsCategory, Product, ProductAdvantage

url = 'http://www.kexinjianji.com/product/hzshntjbz_1/'

def get_one_page(url):
  try:
    headers = {
      "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36"}
    res = requests.get(url=url, headers=headers, timeout=10)
    res.encoding = 'utf-8'
    if res.status_code == 200:
      return res.text
    else:
      return None
  except Exception:
    print('aa')
    return None

if __name__ == '__main__':
  content = get_one_page(url)
  tree = etree.HTML(content)
  # 产品分类url
  catgory_urls = tree.xpath('//div[@class="fdh-01-nav"]/div/h3/a/@href')
  # 处理catgory_urls
  for url in catgory_urls:
    url = 'http://www.kexinjianji.com' + url
    content = get_one_page(url)
    tree = etree.HTML(content)
    # 产品分类
    p_catgory = tree.xpath('//div[@class="cplb-3n-ts-03 b"]/h3/span/text()')
    # 该分类下产品url
    urls = tree.xpath('//div[@class="cplb-3n-ts-03-list"]/dl/dt/a/@href')
    # 处理url
    for url in urls:
      url = 'http://www.kexinjianji.com' + url
      content = get_one_page(url)
      try:
        tree = etree.HTML(content)
        # 产品名称
        title = tree.xpath('//*[@id="wrap"]//h1/text()')
        images = tree.xpath('//div[@class="sol_tj_left"]/a/img/@src')
        # 产品图片
        images_url = 'http://www.kexinjianji.com' + images[0]
        # 性能特点
        xntd = tree.xpath('//div[@class="w"]//div/span/text()|//div[@class="w"]//div/text()')
        # 技术参数
        jscs = tree.xpath('//table')[0]
        jscs_str = etree.tostring(jscs, encoding='utf-8').decode('utf-8')
        # 产品内容
        cpnr = tree.xpath('//div[@class="describe"]/p')
        # 判断是否有这分类,没有则新建
        catgory = p_catgory[0]
        products_catgory = ProductsCategory.objects.filter(name=catgory).exists()
        if products_catgory:
          products_catgory = ProductsCategory.objects.get(name=catgory)
        else:
          products_catgory = ProductsCategory(name=catgory)
          products_catgory.save()
        print(products_catgory)

        # 保存产品图片
        image_content = requests.get(url=images_url)
        ext = images_url.split('.')[-1] # 获取图片类型
        filename = '{}.{}'.format(uuid.uuid4().hex[:8], ext) # 随机生成图片名字
        upload_image_file = ContentFile(image_content.content, name=filename) # 将图片保存为django类型
        product = Product(title=title[0], jscs=jscs_str, image=upload_image_file, category=products_catgory)
        product.save()
        for td in xntd:
          product_advantage = ProductAdvantage()
          product_advantage.content = td
          product_advantage.product = product
          product_advantage.save()
        for cp in cpnr:
          cp = cp.xpath('string(.)')
          product_body = ProductBody()
          product_body.body = cp
          product_body.product = product
          product_body.save()
      except Exception as e:
        print(e)
        print('出错url:' + url)

最后自己手动处理出错url(页面没有获取到技术参数,技术参数是一张图片)

4.总结

1.xpath 获取标签内容时,p标签中嵌套span标签,源码如下

<div class="describe" style="position: relative;">
   <p><span>板  宽:</span>1500mm</p>
   <p><span>板  厚:</span>4.5 mm</p>
   <p><span>出料口:</span>6口</p>
   <p><span>重  量:</span>6000 kg</p>
</div>

使用xpath获取p标签内容
我想得到的效果如下
板 宽:1500mm
板 厚:4.5 mm
出料口:6口
重 量:6000 kg
使用以下xpath 只能分开获取,不是想要的效果

//div[@class="describe"]/p/span/text()|//div[@class="describe"]/p/text()

百度之后找到的解决办法,使用xpath(‘string(.)')
1.先获取所有p标签

cpnr = tree.xpath('//div[@class="describe"]/p')

2.使用**string(.)**获取所有标签所有文本

cp = cp.xpath('string(.)')

循环遍历所有p标签即可

到此这篇关于python利用xpath爬取网上数据并存储到django模型中的文章就介绍到这了,更多相关xpath爬取网上数据存储到django模型内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

时间: 2021-02-23

Python使用xpath实现图片爬取

高性能异步爬虫 目的:在爬虫中使用异步实现高性能的数据爬取操作 异步爬虫的方式: - 多线程.多进程(不建议): 好处:可以为相关阻塞的操作单独开启多线程或进程,阻塞操作就可以异步执行; 弊端:无法无限制的开启多线程或多进程. - 线程池.进程池(适当的使用): 好处:我们可以降低系统对进程或线程创建和销毁的一个频率,从而很好的降低系统的开销: 弊端:池中线程或进程的数据是有上限的. 代码如下 # _*_ coding:utf-8 _*_ """ @FileName :6.4

django数据关系一对多、多对多模型、自关联的建立

一对多模型 一对多的关系,例如员工跟部门.一个部门有多个员工.那么在django怎么建立这种表关系呢? 其实就是利用外键,在多的一方,字段指定外键即可.例如员工和部门,员工是多,所以在员工表直接部门即可. 示例(见19行): class Department(models.Model): name = models.CharField(max_length=20) create_data = models.DateField(auto_now_add=True) is_delete = mode

django的ORM模型的实现原理

ORM模型介绍 随着项目越来越大,采用写原生SQL的方式在代码中会出现大量的SQL语句,那么问题就出现了: SQL语句重复利用率不高,越复杂的SQL语句条件越多,代码越长.会出现很多相近的SQL语句. 很多SQL语句是在业务逻辑中拼出来的,如果有数据库需要更改,就要去修改这些逻辑,这会很容易漏掉对某些SQL语句的修改. 写SQL时容易忽略web安全问题,给未来造成隐患.SQL注入. ORM ,全称 Object Relational Mapping ,中文叫做对象关系映射,通过 ORM 我们可以

Python利用Xpath选择器爬取京东网商品信息

HTML文件其实就是由一组尖括号构成的标签组织起来的,每一对尖括号形式一个标签,标签之间存在上下关系,形成标签树:XPath 使用路径表达式在 XML 文档中选取节点.节点是通过沿着路径或者 step 来选取的. 首先进入京东网,输入自己想要查询的商品,向服务器发送网页请求.在这里小编仍以关键词"狗粮"作为搜索对象,之后得到后面这一串网址: https://search.jd.com/Search?keyword=%E7%8B%97%E7%B2%AE&enc=utf-8,其中参

Python CSS选择器爬取京东网商品信息过程解析

CSS选择器 目前,除了官方文档之外,市面上及网络详细介绍BeautifulSoup使用的技术书籍和博客软文并不多,而在这仅有的资料中介绍CSS选择器的少之又少.在网络爬虫的页面解析中,CCS选择器实际上是一把效率甚高的利器.虽然资料不多,但官方文档却十分详细,然而美中不足的是需要一定的基础才能看懂,而且没有小而精的演示实例. 京东商品图 首先进入京东网,输入自己想要查询的商品,向服务器发送网页请求.在这里小编仍以关键词"狗粮"作为搜索对象,之后得到后面这一串网址: https://s

python利用urllib实现爬取京东网站商品图片的爬虫实例

本例程使用urlib实现的,基于python2.7版本,采用beautifulsoup进行网页分析,没有第三方库的应该安装上之后才能运行,我用的IDE是pycharm,闲话少说,直接上代码! # -*- coding: utf-8 -* import re import os import urllib import urllib2 from bs4 import BeautifulSoup def craw(url,page): html1=urllib2.urlopen(url).read(

Python通过正则库爬取淘宝商品信息代码实例

使用正则库爬取淘宝商品的商品信息,首先我们需要确定想要爬取的对象 我们在淘宝里搜索"python",出来的结果 从url连接中可以得到搜索商品的关键字是"q=",所以我们要用的起始url为:https://s.taobao.com/search?q=python 然后翻页,经过对比发现,翻页后,变化的关键字是s,每次翻页,s便以44的倍数增长(可以数一下每页显示的商品数量,刚好是44) 所以可以根据关键字"s=",来设置爬取的深度(爬取多少页)

c#爬虫爬取京东的商品信息

前言 在一个小项目中,需要用到京东的所有商品ID,因此就用c#写了个简单的爬虫. 在解析HTML中没有使用正则表达式,而是借助开源项目HtmlAgilityPack解析HTML. 下面话不多说了,来一起看看详细的介绍吧 一.下载网页HTML 首先我们写一个公共方法用来下载网页的HTML. 在写下载HTML方法之前,我们需要去查看京东网页请求头的相关信息,在发送请求时需要用到. public static string DownloadHtml(string url, Encoding encod

Python利用Scrapy框架爬取豆瓣电影示例

本文实例讲述了Python利用Scrapy框架爬取豆瓣电影.分享给大家供大家参考,具体如下: 1.概念 Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架. 可以应用在包括数据挖掘,信息处理或存储历史数据等一系列的程序中. 通过Python包管理工具可以很便捷地对scrapy进行安装,如果在安装中报错提示缺少依赖的包,那就通过pip安装所缺的包 pip install scrapy scrapy的组成结构如下图所示 引擎Scrapy Engine,用于中转调度其他部分的信号和数据

python爬虫爬取淘宝商品信息

本文实例为大家分享了python爬取淘宝商品的具体代码,供大家参考,具体内容如下 import requests as req import re def getHTMLText(url): try: r = req.get(url, timeout=30) r.raise_for_status() r.encoding = r.apparent_encoding return r.text except: return "" def parasePage(ilt, html): tr

Python进阶之使用selenium爬取淘宝商品信息功能示例

本文实例讲述了Python进阶之使用selenium爬取淘宝商品信息功能.分享给大家供大家参考,具体如下: # encoding=utf-8 __author__ = 'Jonny' __location__ = '西安' __date__ = '2018-05-14' ''' 需要的基本开发库文件: requests,pymongo,pyquery,selenium 开发流程: 搜索关键字:利用selenium驱动浏览器搜索关键字,得到查询后的商品列表 分析页码并翻页:得到商品页码数,模拟翻页

python爬虫实战之爬取京东商城实例教程

前言 本文主要介绍的是利用python爬取京东商城的方法,文中介绍的非常详细,下面话不多说了,来看看详细的介绍吧. 主要工具 scrapy BeautifulSoup requests 分析步骤 1.打开京东首页,输入裤子将会看到页面跳转到了这里,这就是我们要分析的起点 2.我们可以看到这个页面并不是完全的,当我们往下拉的时候将会看到图片在不停的加载,这就是ajax,但是当我们下拉到底的时候就会看到整个页面加载了60条裤子的信息,我们打开chrome的调试工具,查找页面元素时可以看到每条裤子的信

python爬虫爬取淘宝商品信息(selenum+phontomjs)

本文实例为大家分享了python爬虫爬取淘宝商品的具体代码,供大家参考,具体内容如下 1.需求目标 : 进去淘宝页面,搜索耐克关键词,抓取 商品的标题,链接,价格,城市,旺旺号,付款人数,进去第二层,抓取商品的销售量,款号等. 2.结果展示 3.源代码 # encoding: utf-8 import sys reload(sys) sys.setdefaultencoding('utf-8') import time import pandas as pd time1=time.time()