zll20153246

  在使用python进行数据爬取的时候,我们发现ajax请求比较繁琐,那么有什么好的办法可以解决呢?就是使用selenium自动化工具,模拟输入点击,这样我们就可以不需要知道ajax的请求链接,从而可以直接通过类似人工的操作来模拟,从而可以获取网页数据。我们来举个例子。

  淘宝的首页,我们打开发现没有商品数据的信息,而他的数据都是通过ajax请求获取的,那么我们使用ajax请求这种方法来获取数据简单吗?我们来看看。

  我们在淘宝首页输入美食,进入美食界面我们发现他的链接:https://s.taobao.com/search?q=%E7%BE%8E%E9%A3%9F&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    这么长,他的参数这么多,我们都需要一一来给他赋值,下面就是所有的参数的名称还有信息,而且有的参数我们根本不知道到底是什么意思。所以就很麻烦,我们就使用selenium工具来自动化输入。

  首先我们需要加载淘宝界面:

browser = webdriver.Chrome()
wait=WebDriverWait(browser,10)
client=pymongo.MongoClient(MONGO_URL)
db=client[MONGO_DB]
browser.set_window_size(1400,900)

def serach():
    try:
        browser.get(\'https://www.taobao.com\')
        input = wait.until(
            EC.presence_of_element_located((By.CSS_SELECTOR,\'#q\'))
        )#通过css 选择器找到淘宝主页的输入框
        submit = wait.until(
            EC.element_to_be_clickable((By.CSS_SELECTOR, \'#J_TSearchForm > div.search-button > button\'))
        )#通过css 选择器找到淘宝主页的搜索按钮
        input.send_keys(\'美食\')#向输入框中输入美食
        submit.click()#点击搜索按钮
        total = wait.until(
            EC.presence_of_element_located((By.CSS_SELECTOR, \'#mainsrp-pager > div > div > div > div.total\'))
        )#找到美食界面中所有的页数
        get_product()
        return total.text#返回总页数
    except TimeoutException:
        return serach()#如果没有成功则重新请求

   请求成功后,我们需要来解析网页中商品的信息:

def get_product():
    wait.until(EC.presence_of_element_located((By.CSS_SELECTOR,\'#mainsrp-itemlist .items .item\')))#加载找到的本页中所有的商品
    html=browser.page_source
    doc=pq(html)
    items = doc(\'#mainsrp-itemlist .items .item\').items()#找到本页中商品的列表
    for item in items:
        product = {
            \'image\':item.find(\'.pic .img\').attr(\'src\'),#获取class为pic下的class为.img的src属性,也就是图片链接
            \'price\':item.find(\'.price\').text(),#获取class为priced的文本,也就是价格
            \'deal\':item.find(\'.deal-cnt\').text()[:-3],#获取class为deal-cnt的文本的倒数第三个之前的文本,也就是成交量(多少人付款)
            \'title\':item.find(\'.title\').text(),#获取商品的名称
            \'shop\':item.find(\'.shop\').text(),#获取商品的店铺名称
            \'location\':item.find(\'.location\').text()#获取商品的产地
        }
        save_mongodb(product)

  现在我们只获取了一页的内容,我们需要获取全部的内容,有两种办法:

  第一种:selenium自动点击下一页,但是该方法的缺点就是,如果改页没有加载成功,我们就爬取不到改页的内容,无法判断是否爬取了这页

  第二种:循环,自动输入需要跳转的下一页的页码,通过判断输入的内容和当前页码是否一致判断是否成功加载了本页,我们采用第二种方法。

def next_page(current_page):
    try:
        input = wait.until(
            EC.presence_of_element_located((By.CSS_SELECTOR, \'#mainsrp-pager > div > div > div > div.form > input\'))
        )#获取输入下一页的页码的输入框
        submit = 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(current_page)#在输入框中输入请求的页码
        submit.click()#点击确定
        wait.until(EC.text_to_be_present_in_element((By.CSS_SELECTOR,\'#mainsrp-pager > div > div > div > ul > li.item.active > span\'),str(current_page)))
        # 判断请求的页码是否等于当前页,如果等于说明加载成功
        get_product()
    except TimeoutException:
        return next_page(current_page)# 如果失败则重新加载本页

 

 

 

 

 

然后我们还可以将数据保存在mongdb中,下面是全部代码:

import re

import pymongo
from selenium import webdriver
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from pyquery import PyQuery as pq
from config import *

browser = webdriver.Chrome()
wait=WebDriverWait(browser,10)
client=pymongo.MongoClient(MONGO_URL)
db=client[MONGO_DB]
browser.set_window_size(1400,900)

def serach():
    try:
        browser.get(\'https://www.taobao.com\')
        input = wait.until(
            EC.presence_of_element_located((By.CSS_SELECTOR,\'#q\'))
        )#通过css 选择器找到淘宝主页的输入框
        submit = wait.until(
            EC.element_to_be_clickable((By.CSS_SELECTOR, \'#J_TSearchForm > div.search-button > button\'))
        )#通过css 选择器找到淘宝主页的搜索按钮
        input.send_keys(\'美食\')#向输入框中输入美食
        submit.click()#点击搜索按钮
        total = wait.until(
            EC.presence_of_element_located((By.CSS_SELECTOR, \'#mainsrp-pager > div > div > div > div.total\'))
        )#找到美食界面中所有的页数
        get_product()
        return total.text#返回总页数
    except TimeoutException:
        return serach()#如果没有成功则重新请求

def next_page(current_page):
    try:
        input = wait.until(
            EC.presence_of_element_located((By.CSS_SELECTOR, \'#mainsrp-pager > div > div > div > div.form > input\'))
        )
        submit = 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(current_page)
        submit.click()
        wait.until(EC.text_to_be_present_in_element((By.CSS_SELECTOR,\'#mainsrp-pager > div > div > div > ul > li.item.active > span\'),str(current_page)))
        get_product()
    except TimeoutException:
        return next_page(current_page)
def get_product():
    wait.until(EC.presence_of_element_located((By.CSS_SELECTOR,\'#mainsrp-itemlist .items .item\')))#加载找到的本页中所有的商品
    html=browser.page_source
    doc=pq(html)
    items = doc(\'#mainsrp-itemlist .items .item\').items()#找到本页中商品的列表
    for item in items:
        product = {
            \'image\':item.find(\'.pic .img\').attr(\'src\'),#获取class为pic下的class为.img的src属性,也就是图片链接
            \'price\':item.find(\'.price\').text(),#获取class为priced的文本,也就是价格
            \'deal\':item.find(\'.deal-cnt\').text()[:-3],#获取class为deal-cnt的文本的倒数第三个之前的文本,也就是成交量(多少人付款)
            \'title\':item.find(\'.title\').text(),#获取商品的名称
            \'shop\':item.find(\'.shop\').text(),#获取商品的店铺名称
            \'location\':item.find(\'.location\').text()#获取商品的产地
        }
        save_mongodb(product)

def save_mongodb(result):
    try:
        if db[MONGO_TABLE].insert(result):
            print(\'保存到MongoDb成功!\',result)
    except Exception:
        print(\'存储失败!\')

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

if __name__ == \'__main__\':
    main()

新建config.py文件:

MONGO_URL=\'localhost\'
MONGO_DB=\'taobao\'
MONGO_TABLE=\'meishi\'

下面就是在MongoDB中的商品信息了。

 

分类:

技术点:

相关文章:

  • 2021-05-27
  • 2021-10-01
  • 2022-02-26
  • 2021-07-29
  • 2018-01-03
  • 2021-09-03
  • 2021-12-30
猜你喜欢
  • 2021-10-01
  • 2021-05-23
  • 2021-12-02
  • 2022-02-21
  • 2021-12-20
  • 2022-02-14
相关资源
相似解决方案