利用Python爬虫爬取京东商品的简要信息

本文介绍了一种使用Python实现的JD商品详情页爬虫,详细分析了网页结构,包括商品链接、名称和价格的获取方法,并提供了从URL管理到数据输出的完整爬虫框架。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

转自本人博客园博客:https://www.cnblogs.com/JYU-hsy/p/9673454.html

目录

一、前言

二、何为爬虫

三、JD商品详情页的网页分析

  3.1详情页上指向的其他URL

  3.2商品名称、价格

四、简单爬虫框架

  1.爬虫总调度程序

  2.URL管理器

  3.HTML下载器

  4.HTML解析器

  5.输出程序

五、源码


一、前言

  本文适合有一定Python基础的同学学习Python爬虫,无基础请点击:慕课网——Python入门
  申明:实例的主体框架来自于慕课网——Python开发简单爬虫

  语言:Python2

  IDE:VScode

二、何为爬虫

  传统爬虫从一个或若干初始网页的URL开始,获得初始网页上的URL,然后下载队列中的URL地址对应的网页。解析后抓取网页内容,不断从当前页面上抽取新的URL放入队列,直到满足系统的一定停止条件。同时,它还会根据一定的搜索策略获取我们所需的信息并保存下来。最后为了展示我们爬到的数据,往往还会用HTML的表格或记事本保存我们所需要的数据。
  简单来说,爬虫就是一门用来从互联网上自动获取我们所需数据的技术。

 

三、JD商品详情页的网页分析

  入口URL选择为JD某商品详情页:https://item.jd.com/4224129.html

  我们需要分析的内容主要有:

  3.1详情页上指向的其他URL

    我们打开https://item.jd.com/4224129.html,发现网页上还有很多指向其他商品的链接。

    

    

    通过鼠标右键,查看元素,我们可以发现商品页面上的以上链接均为以下格式: //item.jd.com/数字.html

    

    分析到此,我们就知道抓取网页内容时,从当前页面上抽取新的URL的方法了。

 

  3.2商品名称、价格

  同理,我们在商品名称和价格处点击鼠标右键查看元素

  

      


四、简单爬虫框架

  1.爬虫总调度程序

    即我们的main文件,以入口URL为参数爬取所有相关页面

  2.URL管理器

    维护待爬取和已爬取的URL列表

  3.HTML下载器

    主要功能是下载指定的url,这里用到了urllib2

  4.HTML解析器

    主要功能是获取网页上所需的URL和内容,用到BeautifulSoup

    正则表达式的基础知识可以参见

    re模块(正则表达式) - 人生不如戏 - 博客园

    另外安利一个网站,在写正则表达式的时候可以先测试,很实用

    正则表达式在线测试

  5.输出程序

    将爬取到的数据写入HTML文件中,利用HTML的table展示

 

五、源码

1.爬虫总调度程序

import url_manager, html_downloader, html_parser, html_outputer

class SpiderMain(object):

    def __init__(self):
        self.urls = url_manager.UrlManager()
        self.downloader = html_downloader.Html_DownloaDer()
        self.parser = html_parser.HtmlParser()
        self.outputer = html_outputer.HtmlOutputer()

    #爬虫调度程序
    def craw(self, root_url):
        count = 1
        #入口URL添加进URL管理器 
        self.urls.add_new_url(root_url)
        #启动循环,获取待扒取的URL,然后交给下载器下载页面,调用解析器解析页面
        while self.urls.has_new_url():
            try:
                new_url = self.urls.get_new_url()
                print 'craw',count, ':' ,new_url
                html_cont = self.downloader.download(new_url)

                #得到新的URL列表和内容
                new_urls, new_data = self.parser.parse(new_url,html_cont)

                #新的URL存到URL管理器,同时进行数据的收集
                self.urls.add_new_urls(new_urls)
                self.outputer.collect_data(new_data)

                if count == 10:
                    break
                count = count +1
            except:
                print 'craw dailed'
        #调用output_html展示爬取到的数据
        self.outputer.output_html()


if __name__ == "__main__":
    #入口URL
    root_url = "https://item.jd.com/4224129.html"
    obj_spider = SpiderMain()
    #启动爬虫
    obj_spider.craw(root_url)

 

2.URL管理器

class UrlManager(object):
    def __init__(self):
        #未爬取URL列表,已爬取URL列表
        self.new_urls = set()
        self.old_urls = set()

    #判断管理器中是否有新的待扒取的URL
    def has_new_url(self):
        return len(self.new_urls) != 0

    #获取一个新的待扒取的URL
    def get_new_url(self):
        #pop方法:获取列表中的一个URL并移除它
        new_url = self.new_urls.pop()
        self.old_urls.add(new_url)
        return new_url

    #向管理器添加一个新的URL
    def add_new_url(self, url):
        if url is None:
            return
        #发现新的未添加的URL,则加入待扒取URL列表
        if url not in self.new_urls and url not in self.old_urls:
            self.new_urls.add(url)

    #向管理器添加批量个新的URL
    def add_new_urls(self, urls):
        if urls is None or len(urls) == 0:
            return
        for url in urls:
            self.add_new_url(url)

 

  3.HTML下载器

import urllib2

class Html_DownloaDer():
    def download(self, url):
        if url is None:
            return None
        #调用urllib2库的urlopen方法获取 类文件对象(fd) response
        """ response = urllib2.urlopen(url)"""


        #调用urllib2库的Request方法创建request对象
        request = urllib2.Request(url)

        #添加数据
        request.add_data('a')

        #添加htp和header(伪装成浏览器)
        request.add_header('User-Agent','Mozilla/5.0')

        #发送请求获取结果
        response = urllib2.urlopen(request)


        #获取状态码,200表示成功
        if response.getcode() != 200:
            return None

        return response.read()

 

  4.HTML解析器

from bs4 import BeautifulSoup
import re
import urlparse

class HtmlParser(object):
    def _get_new_urls(self, page_url, soup):
        new_urls = set()
        #获取所有的链接
        #格式如:<a target="_blank" title="华为(HUAWEI)..." href="//item.jd.com/12943624333.html">
        links = soup.find_all('a',href = re.compile(r"//item.jd.com/\d+\.htm"))

         #遍历转化为完整的URL
        for link in links:
            new_url = link['href']
            new_full_url = urlparse.urljoin(page_url,new_url)
            #将结果存到一个新的列表里
            new_urls.add(new_full_url)
        
        return new_urls

    def _new_data(self, page_url, soup):
        res_data = {}
        
        #URL
        res_data['url'] = page_url

        #匹配标题
        #<div class="sku-name">华为(HUAWEI) MateBook X 13英寸超轻薄微边框笔记本(i5-7200U 4G 256G 拓展坞 2K屏 指纹 背光 office)灰</div>
        title_node = soup.find('div',class_ = "sku-name")
        res_data['title'] = title_node.get_text()

        #匹配价格
        #<div class="dd">
        #<span class="p-price"><span>¥</span><span class="price J-p-7430495">4788.00</span></span>
        """下载的网页源码无价格信息<span class="price J-p-7430495"></span></span>!!!!!"""                                                                                                 
        price_node = soup.find('span',class_ = re.compile(r"price\sJ\-p\-\d+"))
        res_data['price'] =price_node.get_text()

        return res_data

    def parse(self, page_url, html_cont):
        if page_url is None or html_cont is None:
            return

        soup = BeautifulSoup(html_cont,'html.parser')
        new_urls = self._get_new_urls(page_url,soup)
        _new_data = self._new_data(page_url,soup)

        return new_urls, _new_data

 

  5.输出程序

class HtmlOutputer(object):
    def __init__(self):
        self.datas = []

    def collect_data(self,data):
        if data is None:
            return
        self.datas.append(data)

    def output_html(self):
        fout = open('output.html','w')

        fout.write("<html>")
        fout.write("<head>")
        fout.write('<meta charset="UTF-8">')        
        fout.write("<body>")
        fout.write("<table>")
        #python默认编码是ascii,中文可能会乱码,故加上encode('utf-8')
        for data in self.datas:
            fout.write("<tr>")
            fout.write("<td>%s</td>" % data['url'])
            fout.write("<td>%s</td>" % data['title'].encode('utf-8'))
            fout.write("<td>%s</td>" % data['price'].encode('utf-8'))
            fout.write("</tr>")

        fout.write("</table>")
        fout.write("</body>")
        fout.write("</head>")
        fout.write("</html>")

 

<think>好的,我现在需要帮助用户解决如何使用Python京东商品数据进行分析和可视化的问题。首先,我得回顾一下用户的问题和提供的引用内容。用户提到了几个引用,都是关于基于Python的系统,使用Django、Vjango、Scrapy、Vue等技术,以及数据采集、清洗、存储、分析和可视化的流程。用户的主要需求是进行数据分析和可视化,所以需要把重点放在这两个部分。 首先,我应该分解步骤。根据引用内容,系统通常包括数据采集、清洗、存储、分析和可视化这几个步骤。用户可能已经了解这些步骤,但需要具体的实现方法。我需要先确认用户是否已经完成了数据采集,或者是否需要指导如何爬取数据。但根据用户的问题,重点在分析和可视化,所以可能假设数据已经采集好了。不过,为了全面起见,可能还是需要简要提到数据采集的方法,比如使用Scrapy或requests库,如引用2和4提到的。 接下来,数据清洗部分,引用2、3、4都提到了数据清洗。可能需要使用pandas处理缺失值、重复数据,格式转换等。然后存储到MySQL数据库,如引用2提到的。之后是数据分析,使用pandas进行统计计算,比如销售总量、销售额、排名等,如引用3所述。最后是可视化,使用Echarts、Matplotlib或Seaborn,结合Flask或Django框架搭建前端展示,如引用4提到的Vue和Echarts。 用户可能需要具体的代码示例,比如如何用pandas分析数据,如何用Matplotlib绘图,或者如何整合到Django或Flask中。但根据示例中的代码结构,可能需要提供Python代码块,比如数据清洗和分析的部分。同时,用户可能需要知道如何将可视化结果展示在网页上,这涉及到前后端的交互,如引用3和4提到的视图函数和Flask框架。 另外,引用中提到的系统功能包括数据概览、类别分析、价格分析、店铺分析等,这些可以作为分析的维度。需要建议用户如何分组数据,计算统计量,并生成相应的图表。 可能还需要考虑使用Jupyter Notebook进行初步的数据探索,然后再将分析过程集成到Web应用中。同时,机器学习部分可能不是用户当前的重点,但引用3提到机器学习,可以作为扩展建议。 现在需要组织这些思路,分步骤回答,确保每个部分都有对应的代码示例和解释。同时,按照用户的要求,生成相关问题,放在最后。要注意使用中文,数学公式用$...$,独立公式用$$...$$,但当前问题可能涉及较少数学公式,但如果有的话需要正确应用。例如,在统计部分可能需要计算平均值、回归分析等,这时候需要正确使用LaTeX格式。 最后,检查引用标记是否正确,每个引用对应的内容是否恰当。例如,引用1提到系统结合了Python、Django、Vue和Scrapy,引用2提到数据处理和可视化的库,引用3提到视图函数和pandas分析,引用4提到Flask和Echarts。在回答过程中,适当引用这些内容,以支持建议的步骤和方法。 总结步骤: 1. 数据采集:使用Scrapy或requests爬取京东数据。 2. 数据清洗:pandas处理缺失值、去重、格式转换。 3. 数据存储:保存到MySQL或其他数据库。 4. 数据分析:pandas进行统计计算,分组聚合。 5. 数据可视化:Matplotlib/Seaborn生成图表,或集成到Web使用Echarts。 6. 系统搭建:使用Django或Flask构建前后端,展示可视化结果。 在代码示例部分,可能需要展示数据清洗和分析的具体操作,比如读取数据、处理缺失值、计算销售额等。可视化部分可以给出绘制折线图或柱状图的代码。同时,提及如何将可视化嵌入到Web应用中,比如通过Flask传递数据到前端模板,使用Echarts渲染。 确保回答结构清晰,分步骤说明,并引用相关的引用标记。最后生成相关问题,比如关于爬虫优化、可视化库选择、处理大数据量的方法等。</think>### 如何用Python京东商品数据进行分析和可视化 以下是基于Python京东商品数据分析与可视化实现步骤,结合数据采集、清洗、存储、分析和展示全流程: --- #### **1. 数据采集与清洗** **步骤1.1 数据爬取** 使用`requests`或`Scrapy`框架爬取京东商品数据,获取商品名称、价格、销量、评价、店铺、产地等信息[^4]。 ```python import requests from bs4 import BeautifulSoup url = "https://search.jd.com/xxxx" headers = {"User-Agent": "Mozilla/5.0"} response = requests.get(url, headers=headers) soup = BeautifulSoup(response.text, 'html.parser') # 解析商品数据并存储到列表或字典中 ``` **步骤1.2 数据清洗** 通过`pandas`处理缺失值、重复项和格式转换: ```python import pandas as pd df = pd.DataFrame(raw_data) # 删除重复项 df.drop_duplicates(inplace=True) # 填充缺失值 df['price'].fillna(df['price'].mean(), inplace=True) # 转换数据类型 df['sales'] = df['sales'].astype(int) ``` --- #### **2. 数据存储** 将清洗后的数据存入MySQL数据库(需提前配置连接): ```python from sqlalchemy import create_engine engine = create_engine('mysql://user:password@localhost/jd_data') df.to_sql('products', engine, if_exists='replace', index=False) ``` --- #### **3. 数据分析** 使用`pandas`进行统计分析,例如计算商品价格分布、销量排名等[^3]: ```python # 计算平均价格和总销量 mean_price = df['price'].mean() total_sales = df['sales'].sum() # 按店铺分组统计 shop_stats = df.groupby('shop_name').agg({ 'price': 'mean', 'sales': 'sum' }).reset_index() # 商品价格区间分析 price_bins = [0, 50, 100, 200, 500, 1000] df['price_group'] = pd.cut(df['price'], bins=price_bins) price_distribution = df['price_group'].value_counts() ``` --- #### **4. 数据可视化** **方法1:静态图表(适合报告生成)** 使用`matplotlib`或`seaborn`生成图表: ```python import matplotlib.pyplot as plt # 绘制价格分布直方图 plt.figure(figsize=(10, 6)) plt.hist(df['price'], bins=20, edgecolor='black') plt.title('商品价格分布') plt.xlabel('价格(元)') plt.ylabel('商品数量') plt.show() ``` **方法2:动态可视化(适合Web展示)** 结合`Flask`+`Echarts`实现交互式图表[^4]: ```python from flask import Flask, render_template import json app = Flask(__name__) @app.route('/') def index(): # 从数据库获取数据并处理 price_data = df['price'].tolist() return render_template('dashboard.html', prices=json.dumps(price_data)) if __name__ == '__main__': app.run() ``` 前端模板(`dashboard.html`)中使用Echarts: ```html <div id="price-chart" style="width: 600px;height:400px;"></div> <script> var chart = echarts.init(document.getElementById('price-chart')); var option = { title: { text: '价格分布直方图' }, xAxis: { type: 'category' }, yAxis: { type: 'value' }, series: [{ type: 'bar', data: {{ prices|safe }} }] }; chart.setOption(option); </script> ``` --- #### **5. 系统集成** 使用`Django`或`Flask`框架搭建完整系统: - **后端**:Django处理数据接口[^1] - **前端**:Vue.js + Echarts展示可视化结果[^2] - **功能模块**:数据概览、类别分析、价格趋势、店铺对比等[^4] --- ###
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值