利用Python爬取京東網商品信息, 實現可見即可爬

利用Python爬取京東商品信息, 實現可見即可爬


  以爬取Macbook商品信息爲例,通過Selenium實現可見即可爬的功能

  關於Selenium的driver配置問題https://blog.csdn.net/qq_19381989/article/details/95893317


一,分析頁面

1. 分析搜索方式

    

 

https://search.jd.com/Search?keyword=MacBook&enc=utf-8&wq=MacBook&pvid=4c32f7c145fb48b2b5910a625501205d

簡化一下就是:https://search.jd.com/Search?keyword=MacBook

可知可以根據URL中的keyword實現搜索,查詢

2. 分析商品元素

    

可見每個商品都在class爲gl-warp clearfix的ul下的li下,商品的信息都在其中的div中,這就好辦了,re,xpath,pyquery都可以得到商品的信息了。

3. 分析如何進行翻頁

    

由URL可知是由page控制且每增加兩位翻一頁

https://search.jd.com/Search?keyword=MacBook&page=3


二,代碼實現

1. 引用的包,全局變量...:

from selenium import webdriver
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
from multiprocessing.pool import Pool
from urllib.parse import quote
from pyquery import PyQuery as pq
import pymongo
import time

options = webdriver.ChromeOptions()
options.add_argument('--headless')
browser = webdriver.Chrome(chrome_options=options)
wait = WebDriverWait(browser,10)
KEYWORD = 'macbook'

MONGO_DB = 'jd'
MONGO_COLLECTION = 'products'
client = pymongo.MongoClient('mongodb://admin:1234qwer@localhost:27017')
db = client[MONGO_DB]


headers = {
    'User-Agent':'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36',
    'x-requested-with':'XMLHttpRequest'#分析頁面的時候看到有ajax解析,應該是用於翻頁的
}

    因爲最後需要將數據存儲在mongodb中,故需要引用pymongo,搜索的關鍵詞由KEYWORD來控制。

    學習時一定要摸清楚selenium的顯式等待和隱式等待,selenium其實就是模仿人類去點擊網頁,這中間js渲染網頁,需要一些時間,如果不做相應的處理會浪費大量的時間,從而影響爬蟲效率,我這裏只是定義了一個簡單的隱式等待。

    其中加入的參數 '--headless' 可以實現隱藏web窗口的功能

2. 搜索爬取塊:

def index_page(page):
    '''
    抓取索引頁
    :param page: 頁碼
    :return: 網頁源碼
    '''
    print('正在爬取第', page, '頁')
    try:
        url = 'https://search.jd.com/Search?keyword={}&enc=utf-8&page={}'.format(quote(KEYWORD),page*2-1)
        print(url)
        browser.get(url)
        time.sleep(2)
        return browser.page_source
        # browser.close()
    except TimeoutException:
        index_page(page)

    由page控制翻頁,page*2-1即可實現一頁一頁的爬取,爬取成功時返回網頁源代碼,不成功時重新爬取該頁信息

3. 提取商品信息塊:

    通過css定位,Google,搜狐都會有右鍵定位的功能,可以結合他們提供的位置然後再進一步優化

    

def get_products(html):
    '''
    提取商品信息
    :param html: 網頁源碼
    :return:
    '''
    # html = browser.page_source
    doc = pq(html)
    items = doc('#J_goodsList > ul > li').items()#因爲全部都在ul下的li中
    for item in items:
        product = {
            'image': item.find('div > div.p-img > a > img').attr('src'),#J_goodsList > ul > li:nth-child(1) > div > div.p-img > a > img
            'price': item.find('div > div.p-price > strong > i').text(),#J_goodsList > ul > li:nth-child(1) > div > div.p-price > strong > i
            'talk': item.find('div > div.p-commit > strong > a').text(),#J_goodsList > ul > li:nth-child(1) > div > div.p-commit > strong > a
            'title': item.find('div > div.p-name.p-name-type-2 > a > em').text(),#J_goodsList > ul > li:nth-child(1) > div > div.p-name.p-name-type-2 > a > em
            'shop': item.find('div.p-shop > span > a').text(),#J_goodsList > ul > li:nth-child(1) > div > div.p-shop > span > a
            'href': item.find('div > div.p-img > a').attr('href'),#J_goodsList > ul > li:nth-child(1) > div > div.p-img > a
        }
        print(product)
        save_to_mongodb(product)#保存到mongodb




def save_to_mongodb(product):
    try:
        if db[MONGO_COLLECTION].insert(product):
            print('Save_Successful!!!')#保存成功!
    except Exception:
        print('Error save OR Done')

利用pyquery定位可以提高定位的速度,定位成功後再由存儲模塊保存


整合代碼

from selenium import webdriver
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
from multiprocessing.pool import Pool
from urllib.parse import quote
from pyquery import PyQuery as pq
import pymongo
import time
import csv

options = webdriver.ChromeOptions()
options.add_argument('--headless')
browser = webdriver.Chrome(chrome_options=options)
wait = WebDriverWait(browser,10)
KEYWORD = 'macbook'

MONGO_DB = 'jd'
MONGO_COLLECTION = 'products'
client = pymongo.MongoClient('mongodb://admin:1234qwer@localhost:27017')
db = client[MONGO_DB]


headers = {
    'User-Agent':'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36',
    'x-requested-with':'XMLHttpRequest'
}


def index_page(page):
    '''
    抓取索引頁
    :param page: 頁碼
    :return: 網頁源碼
    '''
    print('正在爬取第', page, '頁')
    try:
        url = 'https://search.jd.com/Search?keyword={}&enc=utf-8&page={}'.format(quote(KEYWORD),page*2-1)
        print(url)
        browser.get(url)
        time.sleep(2)
        return browser.page_source
        # browser.close()
    except TimeoutException:
        index_page(page)


def get_products(html):
    '''
    提取商品信息
    :param html: 網頁源碼
    :return:
    '''
    # html = browser.page_source
    doc = pq(html)
    items = doc('#J_goodsList > ul > li').items()
    # print(items)
    for item in items:
        # print(item)
        product = {
            'image': item.find('div > div.p-img > a > img').attr('src'),#J_goodsList > ul > li:nth-child(1) > div > div.p-img > a > img
            'price': item.find('div > div.p-price > strong > i').text(),#J_goodsList > ul > li:nth-child(1) > div > div.p-price > strong > i
            'talk': item.find('div > div.p-commit > strong > a').text(),#J_goodsList > ul > li:nth-child(1) > div > div.p-commit > strong > a
            'title': item.find('div > div.p-name.p-name-type-2 > a > em').text(),#J_goodsList > ul > li:nth-child(1) > div > div.p-name.p-name-type-2 > a > em
            'shop': item.find('div.p-shop > span > a').text(),#J_goodsList > ul > li:nth-child(1) > div > div.p-shop > span > a
            # 'href': re.findall('href="(.*?)"',item.find('div > div.p-img > a').html())#J_goodsList > ul > li:nth-child(11) > div > div.p-img > a #J_goodsList > ul > li:nth-child(22) > div > div.p-img > a
            'href': item.find('div > div.p-img > a').attr('href'),#J_goodsList > ul > li:nth-child(1) > div > div.p-img > a
        }
        print(product)
        save_to_mongodb(product)




def save_to_mongodb(product):
    try:
        if db[MONGO_COLLECTION].insert(product):
            print('Save_Successful!!!')
    except Exception:
        print('Error save OR Done')

if __name__ == '__main__':
    # pool = Pool()
    # group = [i for i in range(1,78)]
    # print(group)
    # pool.map(main, group)
    # pool.close()
    # pool.join()
    for i in range(1,78):#一共77頁
        get_products(index_page(i))

這樣子就實現了selenium的可見可爬的功能了

也可以通過搭建pool池,實現多進程爬取網頁,提高爬取速度

三,運行

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章