python3爬虫实战之selenium爬取亚马逊商品

环境

  1. python3.6
  2. PyCharm
  3. 科学上网环境

主要内容

1. 思路

先说一下爬取的思路,用selenium打开关键词的搜索页,然后分析搜索页下的商品链接,再用selenium打开商品页,最后返回商品数据即可。

2. 导入模块
from datetime import date

import requests
import time
import re
from PIL import Image
from bs4 import BeautifulSoup
from pyquery import PyQuery as pq
import openpyxl
from selenium import webdriver
from selenium.common.exceptions import UnexpectedAlertPresentException
from selenium.webdriver import DesiredCapabilities
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
3. 主要代码

上代码之前有几个需要注意的地方

  1. 开启科学上网后爬取亚马逊速度会快
  2. 亚马逊会根据科学上网的地址设置为收货地址
  3. 有的收货地址商品页会不显示价格,比如下面这个商品
    在这里插入图片描述
    在这里插入图片描述
3.1 更换地址
def change_address(postal):
    while True:
        try:
            driver.find_element_by_id('glow-ingress-line1').click()
            # driver.find_element_by_id('nav-global-location-slot').click()
            time.sleep(2)
        except Exception as e:
            driver.refresh()
            time.sleep(10)
            continue
        try:
            driver.find_element_by_id("GLUXChangePostalCodeLink").click()
            time.sleep(2)
        except:
            pass
        try:
            driver.find_element_by_id('GLUXZipUpdateInput').send_keys(postal)
            time.sleep(1)
            break
        except Exception as NoSuchElementException:
            try:
                driver.find_element_by_id('GLUXZipUpdateInput_0').send_keys(postal.split('-')[0])
                time.sleep(1)
                driver.find_element_by_id('GLUXZipUpdateInput_1').send_keys(postal.split('-')[1])
                time.sleep(1)
                break
            except Exception as NoSuchElementException:
                driver.refresh()
                time.sleep(10)
                continue
        print("重新选择地址")
    driver.find_element_by_id('GLUXZipUpdate').click()
    time.sleep(1)
    driver.refresh()
    time.sleep(3)
  1. postal:邮编地址,比如美国华盛顿邮编20237
3.2 解析搜索页
def parse_list(page_source, current_url):
    html = pq(page_source)
    url_front = current_url.split("/s")[0]
    item_urls = html("h2 > a.a-link-normal.a-text-normal").items()

    for s in item_urls:
        url = url_front + s.attr("href")
        yield url
  1. page_source:网页源代码
  2. current_url:搜索页的网址,做拼接使用
3.3 解析商品详情页
def parse_detail(page_source):
    html = pq(page_source)
    attr_list = []

    # 商品标题
    title = html("span#productTitle").text()

    # 详细描述
    li_list = html("ul.a-unordered-list.a-vertical.a-spacing-none li").items()
    li_text_list = []
    for li in li_list:
        li_text_list.append(li.text().strip())

    # 主图
    z_img = html("img#landingImage").attr("data-old-hires")
    if z_img == "":
        z_img = html("img#landingImage").attr("src")

    # 价格
    price = html('span[id*="priceblock"]').text().replace('\xa0', '')
  
    # 评论数
    review_num = ""
    review_num_list = html("#acrCustomerReviewText").items()
    for rn in review_num_list:
        review_num = rn.text()
        break
    if review_num != "":
        review_num = review_num.split(" ")[0]

    # 排名
    rank1 = ""
    rank2 = ""
    tr_list = html("#productDetails_detailBullets_sections1 tr").items()
    for tr in tr_list:
        if "Rank" in tr("th").text():
            rank1 = tr("td > span > span:nth-child(1)").text().strip()
            rank2 = tr("td > span > span:nth-child(3)").text().strip()
            break
    if rank1 == "":
        first_rank = html("#SalesRank")
        if first_rank("b"):
            rank2 = html("#SalesRank > ul").text().replace("\xa0", "")
            first_rank.remove("b")
            first_rank.remove("ul.zg_hrsr")
            first_rank.remove("style")
            rank1 = first_rank.text()
        else:
            first_rank = html("div.attrG tr#SalesRank > td.value")
            rank2 = html("div.attrG tr#SalesRank > td.value ul.zg_hrsr").text().replace("\xa0", "")
            first_rank.remove("ul.zg_hrsr")
            first_rank.remove("style")
            rank1 = first_rank.text()
    if rank1 == "":
        b_html = BeautifulSoup(page_source, 'lxml')
        tr_list = b_html.select("#productDetails_detailBullets_sections1 tr")
        for tr in tr_list:
            if 'Rank' in tr.th.text:
                rank1_list = tr.select("td > span > span:nth-child(1)")
                if rank1_list:
                    rank1 = rank1_list[0].text.strip()
                rank2_list = tr.select("td > span > span:nth-child(3)")
                if rank2_list:
                    rank2 = rank2_list[0].text.strip()

    rank_regex = re.compile("\d(.*?)\s")
    if rank1 != "":
        rank1 = rank_regex.search(rank1).group()
    if rank2 != "":
        rank2 = rank_regex.search(rank2).group()

    score = html("span[data-hook=rating-out-of-text]").text()
    if score == "":
        try:
            score = list(html("#acrPopover > span.a-declarative > a span").items())[0].text()
        except Exception as e:
            score = ""
    if score != "":
        score = score.split(" ")[0].replace(",", ".")

    asin = ''
    attr_list.append(asin)
    attr_list.append(z_img)
    attr_list.append(title)
    attr_list.append(price)
    attr_list.append(score)
    attr_list.append(int(review_num.strip().replace(',', '')) if review_num else 0)
    attr_list.append(int(rank1.strip().replace(',', '')) if rank1 else 0)
    attr_list.append(rank2)

    return attr_list
  1. page_source:网页源代码
  2. 返回商品asin、主图地址、标题、价格、评分、评论人数、大类排名、小类排名
3.4 调用方法
if __name__ == '__main__':
    options = webdriver.ChromeOptions()
    options.add_argument('--disable-gpu')
    options.add_argument("disable-web-security")
    options.add_argument('disable-infobars')
    options.add_experimental_option('excludeSwitches', ['enable-automation'])
    driver = webdriver.Chrome(chrome_options=options)
    wait = WebDriverWait(driver, 20)

    driver.maximize_window()
    row = 2

    search_page_url = 'https://www.amazon.com/s?k=basketball+hoop&crid=1FVAKJZW1GRRW&sprefix=bas%2Caps%2C405&ref=nb_sb_ss_i_1_3&page={}'
    postal = "20237"
    for i in range(1, 2):
        print("正在爬取", search_page_url.format(i))
        driver.get(search_page_url.format(i))
        time.sleep(2)

        if i == 1:
            change_address(postal)

        wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, "div.s-result-list")))

        for url in parse_list(driver.page_source, search_page_url.format(i)):
            js = 'window.open("' + url + '&language=en_US");'
            driver.execute_script(js)

            # 网页窗口句柄集
            handles = driver.window_handles
            # 进行网页窗口切换
            driver.switch_to.window(handles[-1])

            page_source = driver.page_source
            info_list = parse_detail(driver.page_source)
            info_list.append(driver.current_url)

            time.sleep(2)

            asin_regex = re.compile('/dp/(.*?)/')
            asin = asin_regex.findall(driver.current_url)[0]
            info_list[0] = asin

            print(info_list)

            driver.close()
            driver.switch_to.window(handles[0])
    print("爬取结束")

运行结果:
在这里插入图片描述

  • 13
    点赞
  • 49
    收藏
    觉得还不错? 一键收藏
  • 30
    评论
### 回答1: Python爬虫中可以使用Selenium库来爬取网页信息。Selenium可以模拟浏览器行为,能够爬取JavaScript渲染后的网页信息。使用Selenium爬取网页时,需要配合浏览器驱动(如ChromeDriver、FirefoxDriver)使用。 ### 回答2: Python是一种高级编程语言,吸引了大量编程人员和开发者使用Python进行Web开发、数据分析、机器学习和人工智能等领域的开发。爬虫技术正是其中的一项重要技术,用python编写爬虫程序通常更加便捷和灵活。而seleniumPython中主要的爬虫库之一,用于爬取动态Web页面,可以模拟用户在浏览器中的行为,从而获取大量数据。 使用selenium爬取信息可以分为以下几个步骤: 1.安装和导入selenium和webdriver: 首先需要安装适合的版本的selenium包,并导入selenium和webdriver模块: ```python from selenium import webdriver ``` 2.配置浏览器驱动: Selenium需要浏览器驱动(如Chrome,Firefox等)来与其进行交互,需要配置如下: ```python driver = webdriver.Chrome() ``` 其中,Chrome()表示使用Chrome浏览器驱动,如果使用Firefox,则需要改为Firefox()。 3.访问网页: 使用get()函数可以访问指定的网址: ```python driver.get("https://www.baidu.com/") ``` 4.查找元素: 使用selenium的查找元素功能,可以根据元素的ID、name、class、tag等属性进行查找: ```python element = driver.find_element_by_id("kw") # 根据ID查找 element = driver.find_element_by_name("wd") # 根据name查找 element = driver.find_element_by_class_name("s_ipt") # 根据class查找 element = driver.find_element_by_tag_name("input") # 根据tag查找 ``` 5.模拟用户输入/点击: 使用send_keys()函数模拟用户在搜索框中输入关键字,使用click()函数模拟用户在搜索按钮上点击: ```python element.send_keys("Python") element.click() ``` 6.解析数据: 使用webdriver的page_source属性可以获取网页的源代码,然后使用正则表达式或BeautifulSoup库等解析数据。 以上就是使用selenium进行爬虫的主要步骤。实际应用中,需要根据不同的网站和需要爬取的数据进行具体的配置和调整。在使用selenium过程中,需要了解一些常见的使用技巧和注意事项,例如模拟等待时间,处理弹窗、验证码等。同时,也需要遵循爬虫的法律和道德规范,不得进行非法、滥用等行为。 ### 回答3: selenium是一种自动化测试工具,它可以模拟浏览器行为,实现自动化操作。在Python爬虫中,selenium也可以用来爬取需要模拟人工操作的网站数据。 使用selenium可以实现以下操作: 1.自动模拟浏览器打开网页,获取网页源码。 2.模拟用户操作,如点击按钮、填写文本框、下拉选择框等。 3.通过获取网页源码进行数据解析。 基本流程比较简单,首先需要准备好selenium的环境,这需要下载对应的webdriver,这里我使用Chrome浏览器,并且下载了对应版本的chromedriver。 然后通过selenium启动浏览器,在浏览器中进行模拟操作,最后获取网页源码进行数据解析。 具体实现可以参考以下代码: ```python from selenium import webdriver from bs4 import BeautifulSoup # 创建一个Chrome浏览器实例 browser = webdriver.Chrome() # 访问目标网页 browser.get('https://www.example.com') # 模拟点击按钮,等待加载完成 button = browser.find_element_by_xpath('//button[@class="btn"]') button.click() browser.implicitly_wait(5) # 获取网页源码 html = browser.page_source soup = BeautifulSoup(html, 'html.parser') data = soup.find_all('div', class_='data') # 处理数据 for item in data: # do something # 关闭浏览器 browser.quit() ``` 总体来说,selenium是一个强大的爬虫工具,可以应对大部分需要模拟人工操作的场景,但也存在一些缺点,比如速度慢、占用资源高等。因此在具体应用中需要根据实际情况进行选择。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 30
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值