一、创建Scrapy项目

在cmd中输入一下指令创建一个新的scrapy项目及一个爬虫

scrapy startproject JD_Goodscd JD_Goodsscrapy genspider -t basic goods jd.com

二、容器设置

在京东商城笔记本电脑分类下进入一个商品页面,在“”规格与包装”栏下可以看见该笔记本电脑的详细信息

经过筛选,在items.py下设置下列容器(忽略我的Chinglish命名法...):

    #商品名称name = scrapy.Field()#价格price = scrapy.Field()#链接link = scrapy.Field()#内存internalStorage = scrapy.Field()#CPU类型cpuType = scrapy.Field()#CPU型号cpuModel = scrapy.Field()#CPU速度cpuSpeed = scrapy.Field()#CPU核心cpuCore = scrapy.Field()#硬盘容量diskCapacity = scrapy.Field()#固态硬盘SSD = scrapy.Field()#显卡类型GCtype = scrapy.Field()#显示芯片GCcore = scrapy.Field()#显存容量GCcapacity = scrapy.Field()#尺寸size = scrapy.Field()#重量weight = scrapy.Field()

三、爬虫编写

整个项目写完后都用到了这些库,从头开始写的时候可以先一次性import完:

from JD_goods.items import JdGoodsItem
from scrapy.http import Request
import scrapy
import urllib.request
import urllib.error
import re
import json
import pymysql

由于要得到笔记本电脑的详细信息需要进入每台笔记本电脑的单独的页面,所以我选择在第一次请求的时候将所有笔记本电脑的链接爬取到链表中。首先分析每一页的url规律,发现规律为:

url = "https://list.jd.com/list.html?cat=670,671,672&page=" + str(页码) + "&sort=sort_totalsales15_desc&trans=1&JL=6_0_0#J_main"

然后分析页面中包含末尾页数的信息,用正则表达式提取:

    def start_requests(self):#TOTAL为总页数url = "https://list.jd.com/list.html?    cat=670,671,672&page=1&sort=sort_totalsales15_desc&trans=1&JL=6_0_0#J_main"TOTAL = int(re.findall('<em>共<b>(.*?)</b>',urllib.request.urlopen(url).read().decode('utf-8','ignore'))[0])

所以用以下代码将url链接存入list中:

        self.links = []for i in range(1, 21):try:url = "https://list.jd.com/list.html?cat=670,671,672&page=" + str(i) + "&sort=sort_totalsales15_desc&trans=1&JL=6_0_0#J_main"page = urllib.request.urlopen(url).read().decode('utf-8', 'ignore')link_pattern = '<a target="_blank" title="" href="(.*?)">'if self.links is None:self.links = re.findall(link_pattern, page)else:self.links = self.links.extend(re.findall(link_pattern, page))print("第"+str(i)+"页处理完成")except urllib.error.URLError as e:if hasattr(e, 'code'):print(e.code)if hasattr(e, 'reason'):print(e.reason)i -= 1continueexcept Exception as e:print(e)i -= 1continue

发现提取出的商品url前都缺少了“https:”,二次处理:

        for i in range(0,len(self.links)):self.links[i] = 'https:' + self.links[i]

由于之后每次爬取商品的信息时需要在self.links列表中调用不同index对应的url,这里设置一个全局变量index并设置为0,然后start_request方法就结束了:

        global indexindex = 0yield Request(self.links[index],headers=ua)

接下来码parse方法的代码:

首先实例化item对象

data = JdGoodsItem()

然后分析各信息在网页源码中的位置并提取,注意此时link在star_request()中已经提取完了,这里调用index取出,并让index自增,由于xpath不方便提取所需要的标签内容,这里依然使用正则表达式

        data['name'] = response.xpath('//img[@id="spec-img"]/@alt').extract()data['link'] = self.links[index]index += 1page_content = urllib.request.urlopen(data['link']).read().decode('gbk','ignore')pattern1 = '<dt>内存容量</dt>.*?<dd>(.*?)</dd>'pattern2 = '<dt>内存类型</dt>.*?<dd>(.*?)</dd>'result1 = re.findall(pattern1,page_content,re.S)result2 = re.findall(pattern2,page_content,re.S)if len(result1) > 0 and len(result2) > 0:data['internalStorage'] = (result1[0]+'    '+result2[0])elif len(result1) > 0 and len(result2) == 0:data['internalStorage'] = result1[0]elif len(result2) > 0 and len(result1) == 0:data['internalStorage'] = result2[0]else:data['internalStorage'] = ' 'pattern = '<dt>CPU类型</dt><dd>(.*?)</dd>'result = re.findall(pattern,page_content)if len(result) > 0:data['cpuType'] = result[0]else:data['cpuType'] = ' 'pattern = '<dt>CPU型号</dt><dd>(.*?)</dd>'result = re.findall(pattern, page_content)if len(result) > 0:data['cpuModel'] = result[0]else:data['cpuModel'] = ' 'pattern = '<dt>CPU速度</dt><dd>(.*?)</dd>'result = re.findall(pattern,page_content)if len(result) > 0:data['cpuSpeed'] = result[0]else:data['cpuSpeed'] = [' ']pattern = '<dt>核心</dt><dd>(.*?)</dd>'result = re.findall(pattern,page_content)if len(result) > 0:data['cpuCore'] = result[0]else:data['cpuCore'] = ' 'pattern = '<dt>硬盘容量</dt><dd>(.*?)</dd>'result = re.findall(pattern,page_content)if len(result) > 0:data['diskCapacity'] = result[0]else:data['diskCapacity'] = ' 'pattern = '<dt>固态硬盘</dt><dd>(.*?)</dd>'result = re.findall(pattern, page_content)if len(result) > 0:data['SSD'] = result[0]else:data['SSD'] = ' 'pattern = '<dt>类型</dt><dd>(.*?)</dd>'result = re.findall(pattern, page_content)if len(result) > 0:data['GCtype'] = result[0]else:data['GCtype'] = ' 'pattern = '<dt>显示芯片</dt><dd>(.*?)</dd>'result = re.findall(pattern, page_content)if len(result) > 0:data['GCcore'] = result[0]else:data['GCcore'] = ' 'pattern = '<dt>显存容量</dt><dd>(.*?)</dd>'result = re.findall(pattern, page_content)if len(result) > 0:data['GCcapacity'] = result[0]else:data['GCcapacity'] = ' 'pattern = '<dt>尺寸</dt><dd>(.*?)</dd>'result = re.findall(pattern, page_content)if len(result) > 0:data['size'] = result[0]else:data['size'] = ' 'pattern = '<dt>净重</dt><dd>(.*?)</dd>'result = re.findall(pattern, page_content)if len(result) > 0:data['weight'] = result[0]else:data['weight'] = ' '

(其实这里可以另外定义一个函数进行相应操作简化代码,后期有时间我会改进的)

在网页源码中无法找到价格信息,于是采用抓包分析,得到价格所在的json文件地址,然后提取:

        #获取商品价格good_id = re.findall('.*/(.*?).html',data['link'])[0]price_url = 'https://p.3.cn/prices/mgets?&skuIds=J_' + good_idcontent = urllib.request.urlopen(price_url).read()print(price_url)Json = json.loads(content)[0]data['price'] = Json['p']

最后,返回item对象并设置循环爬取:

        yield datafor i in range(1,len(self.links)):url = self.links[i]yield Request(url, callback=self.parse)

至此,爬虫文件的代码就码完了

四、写入Mysql

首先在settings.py中设置好相关信息,然后进入pipelines.py。为了在处理数据时实时反馈,再设置一个全局变量i,然后进行数据处理(我的机子在进行query() insert操作后数据库内还是空白的,于是进行手动commit)

class JdGoodsPipeline(object):global ii = 1def process_item(self, item, spider):database = pymysql.connect(host='127.0.0.1', user='root', password='Zwp0816...', db='JD_Goods')# print("index" + str(i))name = item['name'][0]#print(name)price = item['price']#print(price)internalStorage = item['internalStorage']#print(internalStorage)cpuType = item['cpuType']# print(item['cpuType'])cpuModel = item['cpuModel']# print(item['cpuModel'])cpuSpeed = item['cpuSpeed']# print(item['cpuSpeed'])cpuCore = item['cpuCore']# print(item['cpuCore'])diskCapacity = item['diskCapacity']# print(item['diskCapacity'])SSD = item['SSD']# print(item['SSD'])GCtype = item['GCtype']# print(item['GCtype'])GCcore = item['GCcore']# print(item['GCcore'])GCcapacity = item['GCcapacity']# print(item['GCcapacity'])size = item['size']# print(item['size'])weight = item['weight']# print(item['weight'])link = item['link']sql = "insert into pcInfo values('" + name + "','" + price + "','" + internalStorage + "','" + cpuType + "','" + cpuModel + "','" + cpuSpeed + "','" + cpuCore + "','" + diskCapacity + "','" + SSD + "','" + GCtype + "','" + GCcore + "','" + GCcapacity + "','" + size + "','" + weight + "','" + link + "');"#print(1)database.query(sql)commit = "commit;"#print(2)database.query(commit)global iprint("第" + str(i) + "个商品处理完成")i = i+1database.close()return item

五、后续问题

问题1:在处理json文件获取price的操作次数多了之后会返回 {"error":"pdos_captcha"},因此获取price的方法需要改进。

解决办法:在pduid值后添加100000-999999的随机值

后续跟进:使用上述方法爬取一段时间后还是会返回 {"error":"pdos_captcha"},只能用动态页面渲染的方法了。后续会给出相应代码。

更新:已写出利用动态渲染获取价格和评论数的方法,请移步 利用动态渲染页面对京东笔记本电脑信息爬取

import random
price_url = 'https://p.3.cn/prices/mgets?pduid=' + str(random.randint(100000, 999999)) + '&skuIds=J_' + good_id+ '&ext=11100000&source=item-pc'

Scrapy框架爬虫项目:京东商城笔记本电脑信息爬取相关推荐

  1. python爬取职位信息_爬虫项目 智联-职位信息爬取

    [ { "招聘信息": [ " 职位月薪:15000-20000元/月 工作地点:北京 发布日期:2018-07-24 14:39:49 工作性质:全职 工作经验:3-5 ...

  2. 利用动态渲染页面对京东笔记本电脑信息爬取

    写在前面 之前写过一个爬取京东商品的Scrapy爬虫项目,但是里面价格及评论数是通过逆向工程法获得的,在不使用代理ip的情况下,在爬取一定数量的商品后会被持续要求输入验证码.所以这里写出利用动态页面渲 ...

  3. Scrapy框架爬虫—以京东众筹为例

    Scrapy框架爬虫--以京东众筹为例 第一步, 打开命令提示符,创建一个Scrapy框架: 第二步,定位到创建的文件夹: 第三步,在spider文件夹中创建一个.py文件(注:不要关闭命令提示符): ...

  4. 【2020-10-27】 scrapy爬虫之猎聘招聘信息爬取

    声明:本文只作学习研究,禁止用于非法用途,否则后果自负,如有侵权,请告知删除,谢谢! scrapy爬虫之猎聘招聘信息爬取 1.项目场景 目标网址:https://www.liepin.com/zhao ...

  5. 16-爬虫之scrapy框架手动请求发送实现全站数据爬取03

    scrapy的手动请求发送实现全站数据爬取 yield scrapy.Reques(url,callback) 发起的get请求 callback指定解析函数用于解析数据 yield scrapy.F ...

  6. Scrapy中selenium的应用-----并通过京东图书书籍信息爬取项目进行实操!

    引言------ 在通过scrapy框架进行某些网站数据爬取的时候,往往会碰到页面动态数据加载(ajax)的情况发生,如果直接使用scrapy对其url发请求,是绝对获取不到那部分动态加载出来的数据值 ...

  7. [爬虫] B站番剧信息爬取

    申明:本文对爬取的数据仅做学习使用,不涉及任何商业活动,侵删 简述 本次爬取目标是: 番剧的基本信息(名字, 类型, 集数, 连载or完结, 链接等) 番剧的参数信息(播放量, 点赞, 投币, 追番人 ...

  8. 链家网页爬虫_爬虫实战1-----链家二手房信息爬取

    经过一段机器学习之后,发现实在是太枯燥了,为了增添一些趣味性以及熟练爬虫,在之后会不定时的爬取一些网站 旨在熟悉网页结构--尤其是HTML的元素,ajax存储,json:熟练使用pyspider,sc ...

  9. 用Scrapy对豆瓣top250进行电影详细信息爬取

    简述 为了练习简单的Pandas操作,我用Scrapy爬取了豆瓣Top250的电影信息.Top250页面展现的电影信息和具体电影页面所呈现的内容有些不同(比如演员信息),所以爬取总共用了两部分代码.此 ...

最新文章

  1. 1.2.4 ORACLE_SID的含义
  2. nginx 之负载均衡 :PHP session 跨多台服务器配置
  3. centos7最小安装没有 ifconfig netstat 命令
  4. 干货 | 携程异地多活-MySQL实时双向(多向)复制实践
  5. Python基础day04 作业解析【3道 字典题】
  6. 【杂题集】单题小总结
  7. dubbo知识点总结 持续更新
  8. c++怎么实现数字数组的删除数字_C/C++数据结构:栈结构解析,最简单解析,让你一遍就会...
  9. 水电图wp表示什么_装修水电工入门基础知识,刚入行不懂不用急?老师傅告诉你怎么做...
  10. ETL异构数据源Datax_图形化数据同步_11
  11. Python IDE集成开发工具
  12. 跟工作选择障碍同学聊一聊现实的问题……
  13. puppet进阶指南——service资源详解
  14. 皇帝的新脑-读书笔记
  15. Apache SOLR and Carrot2集成
  16. SQL Server 双机热备份-实现主从复制
  17. plupload踩坑小结
  18. Excel单元格设灰色及锁定
  19. 动态规划和分治法解合唱队形问题
  20. 豆瓣电影Top250信息爬取并保存到excel文件中!

热门文章

  1. JAVA毕业设计HTML5“牧经校园疫情防控网站”设计与实现计算机源码+lw文档+系统+调试部署+数据库
  2. 大厂地震,疯狂裁员大换血,面试冲击大厂Android移动开发工程师就在此时
  3. js 格式化,过万转换成万(W),过亿转化成亿(M)
  4. 转载HTMl转义字符大全
  5. STM32使用Jlink下载出现NO cortex-M SW device Found解决(超详细)
  6. LRU 不知道?这个生活实例一定知道吧!
  7. 有传言任天堂可能会很快推出N64 Classic Mini
  8. oracle cux,EBS增加客制应用CUX:Custom Application
  9. linux fish 中set 设定PATH 和BROWSER
  10. 帝国cms如何导入php模板,帝国CMS模板组导入导出更换模板