用selenium爬取京东商品

写在前面的话上一篇文章我们学习了selenium的使用方法,接下来我们将使用selenium来爬取京东商品信息

温馨提示 :博主使用的系统为win10,使用的python版本为3.6.5

一、网页分析

原来,博主打算写一个能够爬取所有商品信息的爬虫,可是在分析过程中发现,不同商品的网页结构还是不一样的,所以后来就放弃了这个想法,转为只爬取笔记本类商品的信息(若要爬取其它类商品信息,只需要把提取数据的规则改变就好,有兴趣的同学可以自己试试看呀)

用chrome打开笔记本商品首页,我们很容易发现该网页是一个动态加载的网页,因为刚打开网页时只会显示30个商品的信息,可是当我们向下拖动网页的时,它会再次加载剩下的30个商品信息,所以我们就可以通过selenium模拟浏览器下拉网页的过程来获取网页返回的全部商品信息

>>> browser.execute_script("window.scrollTo(0,document.body.scrollHeight)")

笔记本商品首页

另外,我们发现该网站一共有100个网页,当然我们可以通过构造URL来获取每一个网页的内容,但是这里我们还是选择使用selenium模拟浏览器的翻页行为,下拉网页至底部可以发现有一个 下一页 的按钮,我们只需获取该元素并点击即可实现翻页了

>>> next_page = browser.find_element_by_xpath('//a[@class="pn-next" and @onclick]')
>>> next_page.click()

翻页爬取

接下来我们就需要解析每一个网页来获取我们需要的数据了,包括商品名称、商品价格和评论人数,我们发现每一项商品的信息包含在一个li标签里面,那么我们就可以直接使用selenium来选择元素,再使用元素的text属性获取文本值,而这个就是我们需要的数据了

  • 商品价格:browser.find_elements_by_xpath('//div[@class="gl-i-wrap"]/div[2]/strong/i')
  • 商品名称:browser.find_elements_by_xpath('//div[@class="gl-i-wrap"]/div[3]/a/em')
  • 评论人数:browser.find_elements_by_xpath('//div[@class="gl-i-wrap"]/div[4]/strong')

抓取数据

二、编码实现

好了,分析过程很简单,基本思路是使用selenium模拟浏览器的行为,下面是代码实现(只需要短短的几十行代码就可以实现了)

from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
import json
import csv

count = 0

file_format = input('请输入文件保存格式(txt、json、csv):')
while file_format!='txt' and file_format!='json' and file_format!='csv':
    file_format = input('输入错误,请重新输入文件保存格式(txt、json、csv):')
if file_format=='txt' :
    file = open('Jd.txt','w',encoding='utf-8')
elif file_format=='json' :
    file = open('Jd.json','w',encoding='utf-8')
elif file_format=='csv' :
    file = open('Jd.csv','w',encoding='utf-8',newline='')
    writer = csv.writer(file)

browser = webdriver.Chrome()
browser.implicitly_wait(10)
wait = WebDriverWait(browser,10)
start_url = 'https://search.jd.com/Search?keyword=%E7%AC%94%E8%AE%B0%E6%9C%AC&enc=utf-8&wq=%E7%AC%94%E8%AE%B0%E6%9C%AC&pvid=e8604bd75a024b31a9aff06b803229ea'
browser.get(start_url)
browser.execute_script("window.scrollTo(0,document.body.scrollHeight)")

print('Processing')
while True :
    try:
        symbol = wait.until(EC.presence_of_element_located((By.XPATH,'//div[@class="gl-i-wrap"]/div[2]/strong/i')))
        symbol = wait.until(EC.presence_of_element_located((By.XPATH,'//div[@class="gl-i-wrap"]/div[3]/a/em')))
        symbol = wait.until(EC.presence_of_element_located((By.XPATH,'//div[@class="gl-i-wrap"]/div[4]/strong')))
        #symbol = wait.until(EC.presence_of_element_located((By.XPATH,'//div[@class="gl-i-wrap"]/div[5]/span/a')))
    except selenium.common.exceptions.TimeoutException:
        continue
    else:
        prices = browser.find_elements_by_xpath('//div[@class="gl-i-wrap"]/div[2]/strong/i')
        names = browser.find_elements_by_xpath('//div[@class="gl-i-wrap"]/div[3]/a/em')
        commits = browser.find_elements_by_xpath('//div[@class="gl-i-wrap"]/div[4]/strong')
        #shops = browser.find_elements_by_xpath('//div[@class="gl-i-wrap"]/div[5]/span/a')
        
    if file_format=='txt' :
        for i in range(len(prices)):
            count += 1
            print(count)
            file.write('--------------------'+str(count)+'--------------------\n')
            file.write('price:')
            file.write(prices[i].text)
            file.write('\n')
            file.write('name:')
            file.write(names[i].text)
            file.write('\n')
            file.write('commit:')
            file.write(commits[i].text)
            file.write('\n')
            #file.write('shop:')
            #file.write(shops[i].text)
            #file.write('\n')
    elif file_format=='json' :
        for i in range(len(prices)):
            count += 1
            print(count)
            item = {}
            item['price'] = prices[i].text
            item['name'] = names[i].text
            item['commit'] = commits[i].text
            #item['shop'] = shops[i].text
            json.dump(item,file,ensure_ascii = False)
    elif file_format=='csv' :
        for i in range(len(prices)):
            count += 1
            print(count)
            item = {}
            item['price'] = prices[i].text
            item['name'] = names[i].text
            item['commit'] = commits[i].text
            #item['shop'] = shops[i].text
            for key in item:
                writer.writerow([key, item[key]])
    
    try:
        next_page = browser.find_element_by_xpath('//a[@class="pn-next" and @onclick]')
    except selenium.common.exceptions.NoSuchElementException:
        break
    else:
        next_page.click()
        browser.execute_script("window.scrollTo(0,document.body.scrollHeight)")

file,close()
browser.quit()
print('Finished')

写在后面的话 :虽然使用selenium模拟浏览器爬取动态网页十分方便,可是由于selenium需要启动浏览器来辅助工作,所以其运行速度确实比较慢,所以下一篇文章我们将要学习PhantomJS无界面浏览器来加快爬取速度

猜你喜欢

转载自www.cnblogs.com/wsmrzx/p/9556543.html