爬虫原理分析:

py requests 模擬瀏覽器帶SSL證書_爬虫

项目流程设计思路:

py requests 模擬瀏覽器帶SSL證書_爬虫_02

爬虫前奏:安装MongoDB数据库

【1】MongoDB数据库下载(密码:09z1) 【2】MongoDB数据库安装指南 【3】RoboMongo - MongoDB数据库可视化开发工具(密码:ifav) 【如果失效,可以和我联系获取或者百度进行搜索】

使用到的模块:

(1)selenium

    自动化测试工具、支持多种浏览器;
    爬虫中主要用于解决JavaScript渲染问题。

    selenium是一个用于Web应用程序测试的工具。
    selenium自动化测试直接运行在浏览器中,就像真正的用户在操作一样。

# 安装selenium模块命令(在DOS窗口中输入,前提:已配置好环境变量)
pip install selenium

  点击查看selenium模块使用文档


(2)pyquery

    PyQuery库也是一个非常强大又灵活的网页解析库;
    我们使用PyQuery来解析html。

# 安装pyquery模块命令(在DOS窗口中输入,前提:已配置好环境变量)
pip install pyquery

  点击查看pyquery模块使用文档

(3)pymongo(pymongo是操作MongoDB的python模块)

    在这个项目中,我们另外生成一个名为config.py的文件(相当于一个配置文件)。

# 在文件中,我们配置一些MongoDB的相关信息:
MONGO_URL='localhost'
MONGO_DB='taobao'
MONGO_TABLE='products'
KEY_WORD="美食"
SERVICE_ARGS=["--load-images=false", "--disk-cache=true"]

     对配置文件进行分析:
        MONGO_URL:表示连接MongoDB数据库的主机地址
        MONGO_DB:  表示数据库的名字
        MONGO_TABLE:表示数据表的名字
        KEY_WORD:  进行搜索的关键字
        SERVICE_ARGS:
        为了更好、更快的抓取数据并存放到数据库中;
        我们不需要在浏览器中加载图片,并开启磁盘缓冲

# 安装pymongo模块命令(在DOS窗口中输入,前提:已配置好环境变量)
pip install pymongo

  点击查看pymongo模块的官方文档


(4)re
  在该项目中,我们使用re模块

# 对页码多余的部分进行处理,我们只需要总页码的数字即可 
total =int(re.compile("(\d+)").search(total).group(1))

(5)chromeDriver驱动浏览器:

  由于Selenium可以操作各种浏览器进行测试,所以在使用之前我们需要在电脑上安装对应的浏览器。

(摩卡已经将三大浏览器驱动下载地址放到这啦!点击即可跳转~)   【1】Chrome浏览器的驱动chromedriver

  【2】Firefox浏览器的驱动geckodriver

  【3】IE浏览器的驱动IEdriver

  在这个项目中,我们使用Chrome浏览器作为自动化测试的浏览器。
(小伙伴们根据实际情况选择相应的浏览器驱动)

下载好后, 将可执行文件放到python安装目录下的Scripts文件夹中;

py requests 模擬瀏覽器帶SSL證書_Python_03


  测试是否已经安装好,在python命令行中输入:

(如果弹出浏览器,说明执行成功)

from selenium import webdriver
browser = webdriver.Chrome()
browser.get("http://www.baidu.com")

选中搜索输入框,右键选择“检查” 即可定位到该元素的位置。 此时我们右键,选择“Copy” –> 选择“Copy selector”

py requests 模擬瀏覽器帶SSL證書_搜索_04

获取class属性使用: .class属性名称

获取id属性使用:       #id属性名称


Start Project!开启我们的项目~

定义的方法(函数):
(1)def search():
    """在搜索框输入关键字,进行页面跳转
    :return 返回页码数
    """

(2)def next_page(page_number):
    """跳转到下一页"""

(3)def get_products():
    """获取商品信息"""

(4)def save_products(result):
    """将商品的信息存储到MongoDB数据库、txt文件中"""

(5)def main():
    """主方法"""

# 配置文件
MONGO_URL = "localhost"
MONGO_DB = "taobao"
MONGO_TABLE = "products"

KEY_WORD = "美食"

SERVICE_ARGS = ["--load-images=false", "--disk-cache=true"]

# 使用selenium来模拟浏览器抓取淘宝美食商品信息
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 pyquery import PyQuery as pq
from config import *
import re
import pymongo

# 连接MongoDB数据库
client = pymongo.MongoClient(MONGO_URL)
db = client[MONGO_DB]

# 导入selenium模块中的webdriver,使用Chrome()来获取浏览器对象
browser = webdriver.Chrome()

# browser = webdriver.PhantomJS(service_args=SERVICE_ARGS)
# browser.set_window_size(1400, 1000)

# 因为在请求网页时,网页需要加载,那么我们需要等待网页完全加载才能进行下一步
wait = WebDriverWait(browser, 10)


def search():
    """在搜索框输入关键字,进行页面跳转
    :return 返回页码数
    """
    try:
        browser.get("https://www.taobao.com/")

        # EC 表示:期待的条件

        # 输入搜索关键字
        # EC.presence_of_element_located    判断是否加载成功
        input = wait.until(
            EC.presence_of_element_located((By.CSS_SELECTOR, "#q"))
        )

        # 点击搜索按钮,提交搜索关键字
        # EC.element_to_be_clickable    期待鼠标点击
        submit = wait.until(
            EC.element_to_be_clickable((By.CSS_SELECTOR, "#J_TSearchForm > div.search-button > button"))
        )

        # 提交搜索关键字
        input.send_keys(KEY_WORD)
        submit.click()

        total = wait.until(
            EC.presence_of_element_located((By.CSS_SELECTOR, "#mainsrp-pager > div > div > div > div.total"))
        )

        # 获取商品信息
        get_products()

        return total.text
    except TimeoutException:
        print("请求超时")


def next_page(page_number):
    """跳转到下一页"""

    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(page_number)
        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(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)  # 使用PyQuery来解析html
    items = doc("#mainsrp-itemlist .items .item").items()
    for item in items:
        product = {
            # 去掉价格中的换行符
            "price": item.find(".price").text().replace("\n", ""),
            "image": item.find(".pic .img").attr("src"),
            "name": item.find(".title").text(),
            "location": item.find(".location").text(),
            "shop": item.find(".shop").text(),
        }
        """
            需要保存的商品信息:
            (1)商品的图片
            (2)商品的价格
            (3)商品的名字
            (4)商品来源
            (5)商品店铺
        """
        print(product)
        save_products(product)
        print("=" * 30)


def save_products(result):
    """将商品的信息存储到MongoDB数据库、txt文件中"""
    try:
        # 尝试将结果集插入到数据库中
        if db[MONGO_TABLE].insert(result):
            print("存储到MongoDB数据库成功!", result)

        # 将结果集存储到txt文件中
        if result:
            with open("products.txt", "a", encoding="utf-8") as f:
                f.write(str(result) + "\n")
                f.close()
    except Exception:
        print("存储失败!", result)


def main():
    """主方法"""
    try:
        total = search()

        # 对页码多余的部分进行处理
        total = int(re.compile("(\d+)").search(total).group(1))
        # print(total)

        for i in range(2, total + 1):
            next_page(i)
    except Exception:
        print("出错啦!")
    finally:
        browser.close()  # 最后一定都要关闭浏览器


if __name__ == "__main__":
    main()

运行结果:

py requests 模擬瀏覽器帶SSL證書_爬虫_05


py requests 模擬瀏覽器帶SSL證書_Python_06



本项目由焱章同学和摩卡(泽锋)共同完成!