爬虫学习笔记:Selenium爬取淘宝美食 附完整代码

2022-02-22 14:50:26 浏览数 (1)

淘宝的页面也是通过Ajax来抓取相关数据,但是参数比较复杂,甚至包含加密秘钥。使用selenium来模拟浏览器操作,抓取淘宝商品信息,即可做到可见即可爬。

1.准备工作

用selenium抓取淘宝商品,并用pyquery解析得到商品的图片,名称,价格,购买人数,店铺名称和店铺所在位置。

即需要安装selenium,pyquery,以及Chrome浏览器并配置ChromeDriver。

2.页面分析

我们的目标是获取商品的信息,那么先搜索,例如我们搜索美食。即可直接访问https://s.taobao.com/search?q=美食,得到第一页商品信息。如下图:

而我们需要的信息都在每一页商品条目里。如下图:

在页面的最下面,有个分页导航。为100页,要获得所以的信息只需要从第一页到带一百页顺序遍历。采用selenium模拟浏览器不断的遍历即可得到,这里为直接输入页数然后点击确定转跳。这样即使程序中途出错,也可以知道爬到那一页了,而不必从头再来。如下图:

如上图,我们爬取淘宝商品信息,只需要得到总共多少条商品条目,而淘宝默认100页,则只需要每一页商品条目都加载完之后爬取,然后再转跳就好了。用selenium只需要定位到专业和条目即可。

3.爬取每一页

首先构造https://s.taobao.com/search?q=美食,我们将美食定义成变量。则可爬取想要的商品。将要爬取的页数当做参数传入,在方法里我们先访问了搜素商品的链接,然后判断当前页数,如果大于1,就转跳。否则等待加载完成。这里我们使用显示等待,WebDriverWait对象,指定一个最长等待时间。如果在等待时间里匹配了等待条件,则返回结果继续向下执行。我们需要的是等待商品信息加载出来,使用presence_of_element_located这个条件。如果加载成功,则执行后续的get_products()方法。

转跳先定位跳转条目,然后clear()清空输入框,然后使用send_keys()将页码传入输入框,最后点击确定。在跳转那里可以观察到成功跳转到某一页后,页码会高亮显示。这里使用text_to_be_present_in_element()方法判断需要的页码是否出现在高亮的节点里。代码如下:

代码语言:javascript复制
def index_page(page):
 """
 抓取索引页:param page:页码
 """
 print('正在爬取第', page, '页')
 try:
 url = 'https://s.taobao.com/search?q='   quote(KEYWORD)
 browser.get(url)
 if page > 1:
 input = wait.until(
 EC.presence_of_element_located((By.CSS_SELECTOR, '#mainsrp-pager div.form > input')))
 submit = wait.until(
 EC.element_to_be_clickable((By.CSS_SELECTOR, '#mainsrp-pager div.form > span.btn.J_Submit')))
 input.clear()
 input.send_keys(page)
 submit.click()
 wait.until(
 EC.text_to_be_present_in_element((By.CSS_SELECTOR, '#mainsrp-pager li.item.active > span'), str(page)))
 wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, '.m-itemlist .items .item')))
 get_products()
 except TimeoutException:
 index_page(page)

4.解析商品列表

这里我是直接用Chrome浏览器里面指着商品条目点检查得到的定位如下图:

代码如下:

代码语言:javascript复制
def get_products():
 '''
 提取商品
 '''
 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('data-src'),
 'price': item.find('.price').text(),
 'deal': item.find('.deal-cnt').text(),
 'title': item.find('.title').text(),
 'shop': item.find('.shop').text(),
 'location': item.find('.location').text()
 }
 print(product)

 save_to_mongo(product)

5.保存到MongoDB

代码如下:

代码语言:javascript复制
MONGO_URL = 'localhost'
MONGO_DB = 'taobao'
MONGO_COLLECTION = 'foods'
client = pymongo.MongoClient(MONGO_URL)

db = client[MONGO_DB]
def save_to_mongo(result):
 """
 保存至MongoDB
 """
 try:
 if db[MONGO_COLLECTION].insert(result):
 print('存储到MongoDB 成功')
 except Exception: 

 print('存储到MongoDB失败')

6.运行结果

7.总结

基本上实现了可见及可爬,我也是爬虫小新手工科研究生在读。如果考研或者python想要共同学习的请大家多多关照,如有错误请多多指教。下面附上完整代码。期待与大家共同进步。

8.完整代码

代码语言:javascript复制
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 urllib.parse import quote
from pyquery import PyQuery as pq
import pymongo


MAX_PAGE = 100
MONGO_URL = 'localhost'
MONGO_DB = 'taobao'
MONGO_COLLECTION = 'foods'
client = pymongo.MongoClient(MONGO_URL)
db = client[MONGO_DB]


browser = webdriver.Chrome()
wait = WebDriverWait(browser, 10)
KEYWORD = '美食'




def index_page(page):
 """
 抓取索引页:param page:页码
 """
 print('正在爬取第', page, '页')
 try:
 url = 'https://s.taobao.com/search?q='   quote(KEYWORD)
 browser.get(url)
 if page > 1:
 input = wait.until(
 EC.presence_of_element_located((By.CSS_SELECTOR, '#mainsrp-pager div.form > input')))
 submit = wait.until(
 EC.element_to_be_clickable((By.CSS_SELECTOR, '#mainsrp-pager div.form > span.btn.J_Submit')))
 input.clear()
 input.send_keys(page)
 submit.click()
 wait.until(
 EC.text_to_be_present_in_element((By.CSS_SELECTOR, '#mainsrp-pager li.item.active > span'), str(page)))
 wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, '.m-itemlist .items .item')))
 get_products()
 except TimeoutException:
 index_page(page)
 
 
def get_products():
 '''
 提取商品
 '''
 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('data-src'),
 'price': item.find('.price').text(),
 'deal': item.find('.deal-cnt').text(),
 'title': item.find('.title').text(),
 'shop': item.find('.shop').text(),
 'location': item.find('.location').text()
 }
 print(product)
 save_to_mongo(product)
 
def main():
 '''
 遍历每一页
 '''
 for i in range(1, MAX_PAGE 1):
 index_page(i)
 browser.close()
 
def save_to_mongo(result):
 """
 保存至MongoDB
 """
 try:
 if db[MONGO_COLLECTION].insert(result):
 print('存储到MongoDB 成功')
 except Exception: 
 print('存储到MongoDB失败')
 
if __name__ == '__main__':
 main()

0 人点赞