利用selenium爬取京东商城的商品信息思路:
  1、首先进入京东的搜索页面,分析搜索页面信息可以得到路由结构
  2、根据页面信息可以看到京东在搜索页面使用了懒加载,所以为了解决这个问题,使用递归。等待数据全部加载完成。
  3、创建下一页的函数去完成点击事件,获取下一页的数据
  4、首页处理就直接放在脚本运行就好了。
  5、将数据放到mongodb中

可以实现自己定义搜索内容,注意京东的页面数据最大为100页。

不完善的地方:
  1、每次都是利用sleep等待加载。浪费时间
  2、网速不好程序会因为没有获取到标签崩溃。
  3、获取下一页的方式可以改成发送请求的方式
  4、爬取一半重新爬取的数据重复的会重新覆盖数据库旧的数据。

在网速良好的情况下还是能正常的保证数据爬取
# <! -/* author by:daidai */>
# 京东商品信息爬取脚本
from selenium.webdriver import Chrome
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from urllib.parse import urlencode
import mongodemo
import time

driver = Chrome()
chrome_options = Options()
chrome_options.add_experimental_option('excludeSwitches', ['enable-automation'])

# keyword = '电脑'


# 京东搜索页的链接url = https://search.jd.com/Search?keyword=%E7%94%B5%E8%84%91&enc=utf-8&wq=%E7%94%B5%E8%84%91&pvid=53766f90843b4166be83aa2139402e65
# par = {'enc': 'utf-8', 'keyword': keyword, 'wq': keyword}

# kw = urlencode(par)

# url = 'https://search.jd.com/Search?' + kw
# 请求搜索页
# driver.get(url)

# 等待页面加载
# driver.implicitly_wait(5)

# 由于页面有懒加载效果,所以先获取页面的高度
# height = driver.execute_script("return document.body.clientHeight")

# 等待页面加载完成
# driver.implicitly_wait(7)


# 由分析知道,页面有懒加载效果,得知一页数据为60条
def get_data():
    # 获取包裹商品信息的大标签ul
    ul = driver.find_element_by_class_name('gl-warp')
    # 商品列表 在标签li class = "gl-item"中, 完整一页一共60个
    items = ul.find_elements_by_class_name('gl-item')

    if len(items) == 60:
        return items
    # 如果没有获取到60条就递归调用,直到获取该页完整的数据
    else:
        return get_data()


def parser_data(items):
    for item in items:
        # 商品的详细信息都在标签div class=p-img 下 它的下面的a标签下是图片的信息
        link = item.find_element_by_css_selector(".p-img a").get_attribute("href")
        # 图片地址
        img = item.find_element_by_css_selector(".p-img a img").get_attribute("src")
        # 因为在图片中也使用了懒加载,所以做判断
        if not img:
            img = item.find_element_by_css_selector(".p-img a img").get_attribute("data-lazy-img")
            img = "https:" + img
        # 商品价格
        price = item.find_element_by_css_selector(".p-price i").text
        # 商品的标题
        title = item.find_element_by_css_selector(".p-name a em").text
        # 店家名
        trade_name = item.find_element_by_css_selector(".p-shop a").text
        # 评论数
        commit = item.find_element_by_css_selector(".p-commit").text
        data = {"link": link, "img": img, "title": title, "shop_name": trade_name, "commit": commit, "price": price}
        # 存到数据库
        mongodemo.insert_data(data)


def get_next_page():
    # 获取下一页的数据,获取标签
    next_page = driver.find_element_by_partial_link_text("下一页")
    next_page.click()  # 实现点击事件,跳转到下一页
    # 滑动屏幕
    driver.execute_script("""
        window.scrollTo({
            top: %s,
            behavior: "smooth"
        });""" % height)
    time.sleep(1)   #  等待页面加载
    items = get_data()
    parser_data(items)


if __name__ == '__main__':
    keyword = input('请输入要查找的信息:')
    par = {'enc': 'utf-8', 'keyword': keyword, 'wq': keyword}
    kw = urlencode(par)
    url = 'https://search.jd.com/Search?' + kw
    driver.get(url)
    driver.implicitly_wait(10)
    height = driver.execute_script("return document.body.clientHeight")
    driver.implicitly_wait(10)
    # 首页的处理  第一页的信息爬取
    driver.execute_script("""
        window.scrollTo({
            top: %s,
            behavior: "smooth"
        });""" % height)
    items = get_data()
    parser_data(items)

    for i in range(8):
        get_next_page()

    time.sleep(30)
    driver.close()




将数据放到mongodb数据库中

from pymongo import MongoClient

table = None
c = None


def connect_server():
    global table, c
    c = MongoClient('mongodb://root:root@127.0.0.1:27017')  # 获取连接
    table = c['jd']['data']


def insert_data(data):
    if not table:
        connect_server()
    table.insert(data)


def close():
    c.close()

 

 

 

posted on 2019-04-16 20:19  小锦毛  阅读(521)  评论(0编辑  收藏  举报