python 期末大作业 
 
任务  1:  分别爬取京东和淘宝,在手机频道中,找出累积销量(所有商家销售同一型号手
机的销  量之和)最高的  20  款手机。  说明:  1)  销量:京东以评论数为准,淘宝以付款人
数为准。  2)  基础版本:一款手机只看最低配置和最低价格,例如  iPhone  11  只按照  64G 
的价格来计  算。高级版本:一款手机有多个型号,不同的配置算不同的型号,例如  iPhone 
11  64G  算是一种型号,128G  算另一种型号。按照自己的能力选做基础版本或者是高级版
本,  高级版本有加分。  结果展示:  按照销量,以直方图的形式展示手机型号及其销量,
按照销量倒排序。图中的手机型号  请尽量简化,能够区分即可。  一个  figure  中有  2  个子
图,2  个子图分别展示京东和淘宝中,手机价格直方图。   
   
任务  2:  用你爬取下来的数据制作散点图,横轴为手机价格,纵轴为该价格对应的商家个
数。  结果展示:  一个  figure  中有  2  个子图,2  个子图分别展示京东和淘宝中,手机价格
的分布情况。   
   
任务  3:  找出在两个平台上都有售卖的  5  款手机(找销量较大的)  ,由于两个平台上都
有不同的  卖家都销售这些手机,价格也不同,需要将这些卖家销售这款手机的价格,做出
箱型图,比  较不同平台上的价格情况。  结果展示:  一个  figure  中有  5  个子图,每个子
图里面有两个平台上售卖的同一型号手机的  2  个价  格箱型图。   
   
 
 
1.京东爬取代码: 
采用 selenium+scrapy 方式爬取,爬取每一页时先将界面下拉,让其加载出全部
手机,因为京东是先加载出 30 个手机,需要往下拉才会动态加载出后面 30 个手
机,并且爬取每一个手机时,做到了点击进去,选择最低版本,然后爬取最低版
本的价格和手机型号。 
 
import scrapy 
from selenium import webdriver 
from selenium.webdriver.common.by import By 
from selenium.webdriver.support.ui import WebDriverWait 
from selenium.webdriver.support import expected_conditions as EC 
from Scripts.t2017211603.t2017211603.items import MyItem 
 
 
class mySpider(scrapy.spiders.Spider): 
        name = "bupt"    #  爬虫的名字是 bupt 
        allowed_domains = ["search.jd.com/"]    #  允许爬取的网站域名 
        start_urls  =  ["https://search.jd.com/Search?keyword=%E6%89%8B%E6%9C%BA&enc=utf-
8&qrst=1&rt=1&stop=1&vt=2&wq" 
                                    "=shou%27ji&psort=3&click=0"] 
        item = MyItem()    #  生成一个在 items.py 中定义好的 Myitem 对象,用于接收爬取的数
据 
 
        num = 1    #  设定爬取多少页 
 
        def __init__(self): 
                chrome_options = webdriver.ChromeOptions() 
                prefs = {"profile.managed_default_content_settings.images": 2} 
                chrome_options.add_experimental_option("prefs", prefs) 
                self.browser = webdriver.Chrome(chrome_options=chrome_options, 
                                                                               
executable_path=r"C:\Users\xingu\Desktop\chromedriver.exe") 
 
        def start_requests(self): 
                self.browser.implicitly_wait(30) 
                self.browser.get(self.start_urls[0]) 
                for url in self.start_urls: 
                        yield scrapy.Request(url=url, callback=self.parse) 
 
        #  初始 URL,即爬虫爬取的第一个 URL 
        def parse(self, response):    #  解析爬取的内容 
                index = 1 
                print('------正在第',self.num,'页---') 
                for each in response.xpath("/html/body/div[6]/div[2]/div[2]/div[1]/div/div[2]/ul/*"): 
                        #  用 xpath 来解析 html,div 标签中的数据,就是我们需要的数据 
 
                        self.item['price'] = each.xpath("div/div[3]/strong/i/text()").extract()[0] 
                        self.item['num'] = each.xpath("div/div[5]/strong/a/text()").extract()[0] 
                        self.item['store'] = each.xpath("div/div[7]/span/a/text()").extract() 
                        self.item['url'] = each.xpath('div/div[1]/a/@href').extract() 
                        a = self.browser.find_element_by_xpath( 
                                "/html/body/div[6]/div[2]/div[2]/div[1]/div/div[2]/ul/li["  +  str(index)  + 
"]/div/div[1]/a") 
                        index += 1 
                        self.browser.execute_script("arguments[0].click();", a) 
                        windows = self.browser.window_handles 
                        self.browser.switch_to.window(windows[1]) 
                        print("11111111") 
 
                        try: 
= 
= 
                                WebDriverWait(self.browser, 1, 0.01).until( 
                                        EC.presence_of_element_located((By.CSS_SELECTOR, 
'ul.parameter2.p-parameter-list')) 
                                ) 
                                print("222222222") 
                                # //*[@id="detail"]/div[2]/div[1]/div[1]/ul[3]/li[1] 
 
                                self.item['name'] 
self.browser.find_element_by_css_selector("ul.parameter2.p-parameter-list > " 
                                                                                                                                                           
"li:nth-child(1)").text 
                                try: 
 
                                        if u'choose-attr-2' in self.browser.page_source: 
                                                #  如果没有选择版本项就不用点击 
                                                path_price 
self.browser.find_element_by_xpath('//*[@id="choose-attr-2"]/div[2]/div[1]') 
                                                path_price.click() 
                                                print('click') 
                                                self.item['price'] 
self.browser.find_element_by_css_selector('div.dd > span.p-price>' 
                                                                                                                                                                             
'span:nth-child(2) ').text 
                                                print("find the lowest price") 
                                        else: 
                                                print("无选择版本项") 
                                except: 
                                        print('can\'t find price') 
                                print("3333333333") 
                        except: 
                                pass 
                        finally: 
                                self.browser.close() 
                                print("close!!!!!!") 
                        ##item-detail > div.p-parameter > ul > li:nth-child(1) 
                        #self.browser.close() 
                        #self.browser.switch_to.window(windows[0]) 
                        if    self.item['price'] and self.item['num']:    #  去掉值为空的数据 
                                if not self.item['store']: 
                                        self.item['store'] = '自营' 
                                else: 
                                        self.item['store'] = self.item['store'][0] 
                                yield (self.item)    #  返回 item 数据给到 pipelines 模块 
                if self.num < 100: 
= 
= 
                        b 
self.browser.find_element_by_xpath("/html/body/div[6]/div[2]/div[2]/div[1]/div/div[3]/div/spa
n[1]/a[9]") 
                        # /html/body/div[6]/div[2]/div[2]/div[1]/div/div[3]/div/span[1]/a[9] 
                        b.click() 
                        # time.sleep(2) 
                        url = self.browser.current_url 
                        yield scrapy.Request(url=url, callback=self.parse, dont_filter=True) 
                        self.num += 1 
 
2.京东数据处理代码: 
 
import numpy as np 
import pandas as pd 
#1.打开 CSV 文件 
file = 'mobilephone_jingdong.csv' 
df = pd.read_csv(file,encoding='utf-8') 
df = df.drop_duplicates(keep='first')#  只保存第一条重复数据 
df['name']=df['name'].str.replace('商品名称:','') 
df['num']=df['num'].str.replace('+','') 
for index,row in df.iterrows(): 
        print('---第',index,'行---',row['num']) 
        if '万' in str(row['num']): 
                row['num']=row['num'].replace('万','') 
                row['num']=float(row['num'])*10000 
                print('hou:',row['num']) 
        df['num'][index]=int(row['num']) 
df = df.drop(df[df.num<3000].index)#将销量太低的去掉 
df=df.drop(df[df['name'].map(len) > 20].index)#将一些名称太长的无效数据去掉 
print(df['name']) 
print(df['num']) 
df.to_csv("jingdong_result1.csv",encoding="utf-8") 
 
3.淘宝数据的爬取: 
应对反爬的方式:使用 selenium 模拟浏览器方式爬取,先通过以某个端口打
开 chrome 浏览器,手动登录淘宝,防止留下 selenium 指纹被淘宝封号: 
再通过 9399 端口将浏览器控制,这样可以尽量不被淘宝检测到。先将手机价格,
付款人数,店名,店家的链接爬取出来,再通过访问链接得到手机的品牌和具体
 
型号。 
  爬取链接的代码: 
import scrapy 
from selenium import webdriver 
from selenium.webdriver.common.by import By 
from selenium.webdriver.support.ui import WebDriverWait 
from selenium.webdriver.support import expected_conditions as EC 
from Scripts.test2.test2.items import MyItem 
import csv 
import time 
class mySpider(scrapy.spiders.Spider): 
        name = "bupt"    #  爬虫的名字是 bupt 
        allowed_domains = ["s.taobao.com/"]    #  允许爬取的网站域名 
        start_urls 
= 
["https://s.taobao.com/search?q=%E6%89%8B%E6%9C%BA&imgfile=&commend=all&ssid=s5-
e&search_type=item&" 
                                    "sourceId=tb.index&spm=a21bo.2017.201856-taobao-
item.1&ie=utf8&initiative_id=tbindexz_20170306"] 
        item = MyItem()    #  生成一个在 items.py 中定义好的 Myitem 对象,用于接收爬取的数
据 
        num = 1    #  设定爬取多少页 
        #chrome.exe --remote-debugging-port=9399 --user-data-dir="D:\test" 
        def __init__(self): 
['enable-
                chrome_options=webdriver.ChromeOptions() 
                chrome_options.add_experimental_option('debuggerAddress', '127.0.0.1:9399') 
                #chrome_options.add_experimental_option('excludeSwitches', 
automation']) 
                self.browser 
= 
webdriver.Chrome(executable_path=r"C:\Users\xingu\Desktop\chromedriver.exe",chrome_o
ptions=chrome_options) 
               
#executable_path="C:\\Users\\xingu\AppData\Local\Google\Chrome\Application\chrome_p
roxy.exe" 
                self.wait = WebDriverWait(self.browser, 10) 
 
        def start_requests(self): 
                self.browser.implicitly_wait(30) 
                self.browser.get(self.start_urls[0]) 
                self.browser.implicitly_wait(50) 
                for url in self.start_urls: 
                        yield scrapy.Request(url=url, callback=self.parse) 
                #yield scrapy.Request(url=self.browser.current_url, callback=self.parse) 
        #  初始 URL,即爬虫爬取的第一个 URL 
        def parse(self, response):    #  解析爬取的内容 
                index = 1 
                print("ok") 
                print('----正在获取第', self.num, '页----') 
                for each in response.xpath('//*[@id="mainsrp-itemlist"]/div/div/div[1]/*'): 
                        #  用 xpath 来解析 html,div 标签中的数据,就是我们需要的数据 
#//*[@id="mainsrp-itemlist"]/div/div/div[1]/div[1] 
                        #//*[@id="mainsrp-itemlist"]/div/div/div[1]/div[2]/div[2]/div[3]/div[1]/a 
                        url=each.xpath('div[1]/div/div[1]/a/@href').extract() 
                        self.item['num']=each.xpath('div[2]/div[1]/div[2]/text()').extract() 
                        self.item['price']=each.xpath('div[2]/div[1]/div[1]/strong/text()').extract() 
                        self.item['store'] = each.xpath('div[2]/div[3]/div[1]/a/span[2]/text()').extract() 
                        if not self.item['store']: 
                                self.item['store'] = each.xpath('div[2]/div[3]/div[1]/a/text()').extract() 
                        self.item['link']=url 
                        print(url) 
 
                        ##mainsrp-pager > div > div > div > div.form > span.btn.J_Submit 
                        yield (self.item)    #  返回 item 数据给到 pipelines 模块 
                if self.num < 100: 
                        self.num += 1 
                        input = self.wait.until( 
                                EC.presence_of_element_located((By.CSS_SELECTOR,  "#mainsrp-pager  > 
div > div > div > div.form > input")) 
                        ) 
                        #  提交按钮 
                        submit = self.wait.until( 
                                EC.element_to_be_clickable( 
                                        (By.CSS_SELECTOR, "#mainsrp-pager > div > div > div > div.form > 
span.btn.J_Submit")) 
                        ) 
                        input.clear() 
                        input.send_keys(self.num) 
                        self.browser.execute_script("arguments[0].click();", submit) 
                        time.sleep(1) 
 
                        print('click') 
                        yield 
dont_filter=True) 
 
scrapy.Request(url=self.browser.current_url, 
callback=self.parse, 
  访问链接爬取手机具体品牌和型号的代码: 
 
import numpy as np 
import pandas as pd 
from selenium import webdriver 
#1.打开 CSV 文件 
file = 'result-taobao.csv' 
df = pd.read_csv(file,encoding='utf-8') 
df = df.drop_duplicates(keep='first')#  保存第一条重复数据 
df['brand']="" 
df['type']="" 
browser = webdriver.Chrome(executable_path=r"C:\Users\xingu\Desktop\chromedriver.exe") 
for i in range(len(df['link'])): 
        try: 
                #//*[@id="J_Attrs"]/table[1]/tbody/tr[19]/td 
                #//*[@id="J_Attrs"]/table[1]/tbody/tr[6]/td 
                print('----正在爬第',i,'页-----') 
                print(df['link'][i][2:-2]) 
                if 'https:' in df['link'][i][2:-2]: 
                        browser.get(df['link'][i][2:-2]) 
                else: 
                        browser.get('https:'+df['link'][i][2:-2]) 
                browser.implicitly_wait(5) 
                browser.execute_script('window.scrollTo(0, document.body.scrollHeight)') 
                print('start') 
 
                df['brand'][i] 
= 
= 
browser.find_element_by_xpath('//*[@id="J_Attrs"]/table[1]/tbody/tr[19]/td').get_attribute('t
extContent') 
                df['type'][i] 
browser.find_element_by_xpath('//*[@id="J_Attrs"]/table[1]/tbody/tr[20]/td').get_attribute('t
extContent') 
                print('1:',df['brand'][i]) 
        except: 
                try: 
                        ##tb_attributes > ul.tb-attributes-list.tb-attributes-fix > li:nth-child(1) > p:nth-
child(2) 
                        df['brand'][i] = browser.find_element_by_css_selector( 
                                '#tb_attributes  >  ul.tb-attributes-list.tb-attributes-fix  >  li:nth-child(1)  > 
p:nth-child(2)').get_attribute( 
                                'textContent') 
                        df['type'][i] = browser.find_element_by_css_selector( 
                                '#tb_attributes  >  ul.tb-attributes-list.tb-attributes-fix  >  li:nth-child(1)  > 
p:nth-child(3)').get_attribute( 
                                'textContent') 
                        print('2:', df['brand'][i]) 
                except: 
                        try: 
                                df['brand'][i] = browser.find_element_by_css_selector( 
                                        '#attributes > ul > li:nth-child(3)').get_attribute('textContent') 
                                df['type'][i] = browser.find_element_by_css_selector( 
                                        '#attributes > ul > li:nth-child(4)').get_attribute('textContent') 
                                print('3:', df['brand'][i]) 
                        except: 
                                df['brand'][i]='' 
                                df['type'][i]='' 
                                print('not find') 
df.to_csv("result1.csv",encoding="utf-8") 
 
4.淘宝数据的处理: 
 
import numpy as np 
import pandas as pd 
#1.打开 CSV 文件 
file = 'taobao.csv' 
df = pd.read_csv(file,encoding='utf-8') 
df = df.drop_duplicates(keep='first')#  只保存第一条重复数据 
df.dropna(axis='index',  how='all',  subset=['brand','type'],  inplace=True)#删除品牌和类型为
空的数据 
df['brand']=df['brand'].str.replace('品牌: ','')