使用selenium模拟浏览器抓取淘宝美食信息

大概思路:

1. 首先,访问淘宝主页面,在搜索框输入关键字,输入回车或点击搜索按钮,跳转到具体的关键词页面。

2. 对于关键词页面的解析。由于后台数据传到前台采取的是ajax技术,所以要么对ajax请求和返回json文件进行解析

    要么就是控制浏览器,等到ajax请求加载到前台后,再从前台页面中取得数据。这就是用selenium模拟浏览器爬取数据

    的主要方式。

3. 要能够得到总共要爬取的页面数,然后对页面数进行循环。

4. 由于前台是ajax方式,控制分页的控件,实现浏览器的加载而不是通过构建url来requests.get方法访问

5.得到具体的每个页面,html = browser.page_source 

6.通过pyquery来对页面进行解析。构建字典类型,配置MongoDB,将字典直接存储到MongoDB中。


遇到的问题:

在得到页面后,要控制页面,比如输入文本框,点击按钮等都可以,查看网页源代码,用css选择器,右键点击copy selection

得到具体的css选择器。

由于要等待浏览器加载出我们的内容,所以用到了显式等待。这里要特别留意显示等待的expect condition 即 EC

常用的 EC 有

EC.presence_of_element_located((By.CSS_SELECTOR,'#mainsrp-pager > div > div > div > div.form > input'))

或者

EC.text_to_be_present_in_element((By.CSS_SELECTOR,'#mainsrp-pager > div'),str(page_number))

这个是当前分页下的active分页框中出现了文本值 当前页的页码。

还有,在用css选择器对页面中的元素进行选择时,如果在爬取过程中出现了有时出错有时不出错的情况

大部分是由于css选择器没写好。

本文是放弃了对分页按钮控件的选择,直接通过在文本框中输入回车来实现跳转。




#-*-coding:utf-8-*-
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 selenium.common.exceptions import TimeoutException
from selenium.webdriver.common.keys import Keys
from pyquery import PyQuery as pq
import re
from config import *
import pymongo

client = pymongo.MongoClient(MONGO_URL)
db = client[MONGO_DB]



browser = webdriver.Chrome()
wait = WebDriverWait(browser, 10)
def search(keyword):
    try:
        browser.get('https://www.taobao.com/')
        #这里需要判断是否得到成功的信息
        input_element = WebDriverWait(browser, 10).until(
            EC.presence_of_element_located((By.CSS_SELECTOR, "#q"))
        )
        submit_element = WebDriverWait(browser, 10).until(
            EC.element_to_be_clickable((By.CSS_SELECTOR,'.btn-search.tb-bg'))
        )
        input_element.send_keys(keyword)
        submit_element.click()
        total = WebDriverWait(browser, 10).until(
            EC.presence_of_element_located((By.CSS_SELECTOR, "#mainsrp-pager > div > div > div > div.total"))
        )
        get_products()
        return total.text
    except TimeoutException:
        return search()

def next_page(page_number):
    try:
        input_element = wait.until(
            EC.presence_of_element_located((By.CSS_SELECTOR,'#mainsrp-pager > div > div > div > div.form > input'))
        )
        input_element.clear()
        input_element.send_keys(page_number)
        input_element.send_keys(Keys.ENTER)
        wait.until(EC.text_to_be_present_in_element((By.CSS_SELECTOR,'#mainsrp-pager > div > div > div > ul > li.item.active > span'),str(page_number)))
        get_products()
    except TimeoutException:
        next_page(page_number)

def get_products():
    wait.until(EC.presence_of_element_located((By.CSS_SELECTOR,'#mainsrp-itemlist .items .item')))
    html = browser.page_source
    doc = pq(html)
    all_items = doc('#mainsrp-itemlist .items .item').items()
    for one in all_items:
        product = {
            'image':one.find('.pic .J_ItemPic.img').attr('src'),
            'price':one.find('.price.g_price.g_price-highlight').text(),
            'deal':one.find('.deal-cnt').text()[:-3],
            'title':one.find('.title').text(),
            'shop':one.find('.shop').text(),
            'location':one.find('.location').text()
        }
        save_to_mongo(product)

def save_to_mongo(result):
    try:
        if db[MONGO_TABLE].insert(result):
            print('存储到MONGODB成功',result)
    except Exception:
        print('存储失败',result)




def main():
    try:
        total = search('背包')
        pagenum = int(re.compile('(\d+)').search(total).group(1))
        for i in range(2,pagenum+1):
            next_page(i)
    except Exception:
        print('出错了')
    finally:
        browser.close()


if __name__ == '__main__':
    main()

mongoDB配置文件

#-*-coding:utf-8-*-
MONGO_URL = 'localhost'
MONGO_DB = 'taobao'
MONGO_TABLE = 'product'

启动MongoDB服务器;


运行结果:


















评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值