在练习爬虫过程中,拿阿里的tb练了练手,抓取其中商品的名称,标价,地址,店铺,商品图片等
并将信息写入excel表格,将图片存入相应的文件夹中。
分析某宝页面,发现页面源码当中并没有我们想要的信息,通过抓包工具分析
数据在如上图的接口中,并且这个接口的cookie是动态的,所以通过传统的requests需要较为复杂的js逆向知识。所以这里可以利用selenium自动化框架通过定位Xpath来抓取,较为简单方便,抓取速度与requests差不多,并且只要掌握Xpath语法即可。
import requests
from selenium import webdriver
import time
import random
import xlwt
from selenium.webdriver.common.by import By
首先上方为需要用到的包,主要为selenium自动操作chrome浏览器,requests用于请求下载图片,xlwt用于将数据写入excel。
首先用xpath定位目标元素,在登录界面不详细做过多的赘述。这里直接到需要抓取的页面中。
通过分析xpath,我们可以知道每一个商品信息都放在class属性为items下的所有div标签,所以我们可以先获取这里的所有div标签,然后遍历div标签,得到具体的信息。
divs = driver.find_elements(by=By.XPATH, value='//div[@class="grid g-clearfix"]/div/div') # 所有的div标签
继续分析每个div下的标签,可以看到:
付款人数在deal-cnt中,地址在location中,详情页地址在row row-2 title中的a标签下。
图片的地址在class=“pic”下的a标签中的data-src的值。分析完成,下面就是进入代码环节:
def get_data():
# headers={"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.64 Safari/537.36 Edg/101.0.1210.53",
# "Host": "g-search1.alicdn.com"}
global col
global row
divs = driver.find_elements(by=By.XPATH, value='//div[@class="grid g-clearfix"]/div/div') # 所有的div标签
for div in divs:
test = div.find_element(by=By.XPATH, value='.//div[@class="row row-2 title"]/a').text # 商品名字
price = div.find_element(by=By.XPATH, value='.//strong').text + '元' # 商品价格
deal = div.find_element(by=By.XPATH, value='.//div[@class="deal-cnt"]').text # 付款人数
name = div.find_element(by=By.XPATH, value='.//div[@class="shop"]/a/span[2]').text # 店铺名称
location = div.find_element(by=By.XPATH, value='.//div[@class="location"]').text # 店铺地点
detail_url = div.find_element(by=By.XPATH, value='.//div[@class="row row-2 title"]/a').get_attribute(
'href') # 详情页地址
img_data_url = div.find_element(by=By.XPATH,
value='.//div[@class="pic-box J_MouseEneterLeave J_PicBox"]//a/img').get_attribute(
'data-src')
if 'http' not in img_data_url: # 少量url有前缀http,这里处理一下
img_data_url = "http:" + img_data_url
这里就是获取信息的函数。信息获取完毕,将信息写入excel表格中,将图片批量下载至相应文件夹中即可。完整代码如下:
import requests
from selenium import webdriver
import time
import random
import xlwt
from selenium.webdriver.common.by import By
def get_data():
# headers={"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.64 Safari/537.36 Edg/101.0.1210.53",
# "Host": "g-search1.alicdn.com"}
global col
global row
divs = driver.find_elements(by=By.XPATH, value='//div[@class="grid g-clearfix"]/div/div') # 所有的div标签
for div in divs:
test = div.find_element(by=By.XPATH, value='.//div[@class="row row-2 title"]/a').text # 商品名字
price = div.find_element(by=By.XPATH, value='.//strong').text + '元' # 商品价格
deal = div.find_element(by=By.XPATH, value='.//div[@class="deal-cnt"]').text # 付款人数
name = div.find_element(by=By.XPATH, value='.//div[@class="shop"]/a/span[2]').text # 店铺名称
location = div.find_element(by=By.XPATH, value='.//div[@class="location"]').text # 店铺地点
detail_url = div.find_element(by=By.XPATH, value='.//div[@class="row row-2 title"]/a').get_attribute(
'href') # 详情页地址
img_data_url = div.find_element(by=By.XPATH,
value='.//div[@class="pic-box J_MouseEneterLeave J_PicBox"]//a/img').get_attribute(
'data-src')
if 'http' not in img_data_url: # 少量url有前缀http,这里处理一下
img_data_url = "http:" + img_data_url
with open("./商品图片/{}.jpg".format(row), 'wb') as fp:
fp.write(requests.get(img_data_url).content) # 下载商品图片到文件夹
work_sheet.write(row, col, test) # 写入excel
work_sheet.write(row, col + 1, price)
work_sheet.write(row, col + 2, deal)
work_sheet.write(row, col + 3, name)
work_sheet.write(row, col + 4, location)
work_sheet.write(row, col + 5, detail_url)
row += 1
print(test, price, deal, name, location, detail_url)
if __name__ == '__main__':
div_list = ["商品名字", "商品价格", "付款人数", "店铺名称", "店铺地点", "详情页地址"]
col = 0 # 设置行、列
row = 1
work_book = xlwt.Workbook(encoding='utf-8') # 创建工作簿
work_sheet = work_book.add_sheet('tb_shopping') # 创建一张表
# pattern = xlwt.Pattern() # 设置单元格颜色
# pattern.pattern = xlwt.Pattern.SOLID_PATTERN
# pattern.pattern_fore_colour = 5
for i in range(6): # 设置标头
work_sheet.col(i).width = 4444
work_sheet.write(0, i, div_list[i])
word = input('请输入要搜索的关键字:')
driver = webdriver.Chrome("D:/chrome/chromedriver.exe")
driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", # 修改浏览器属性,跳过滑动验证
{"source": """Object.defineProperty(navigator, 'webdriver', {get: () => undefined})"""})
driver.get('https://www.taobao.com/')
driver.implicitly_wait(10)
driver.maximize_window()
driver.find_element(by=By.XPATH, value='//*[@id="q"]').send_keys(word)
time.sleep(random.randint(1, 3))
driver.find_element(by=By.XPATH, value='//*[@id="J_TSearchForm"]/div[1]/button').click()
time.sleep(random.randint(1, 3))
"""用户账号及密码登录"""
driver.find_element(by=By.XPATH, value='//*[@id="fm-login-id"]').send_keys('......') # 输入账号密码
time.sleep(random.randint(1, 3))
driver.find_element(by=By.XPATH, value='//*[@id="fm-login-password"]').send_keys('.......')
time.sleep(random.randint(1, 3))
driver.find_element(by=By.XPATH, value='//*[@id="login-form"]/div[4]/button').click()
time.sleep(random.randint(1, 3))
for page in range(0, 7):
print(f'正在爬取第{page + 1}页')
get_data()
driver.find_element(by=By.XPATH, value='//li[@class="item next"]/a[@class="J_Ajax num icon-tag"]').click()
time.sleep(random.randint(2, 3))
work_book.save("自行命名.xls")
总结:通过selenium爬取时,可以绕过一些复杂的js逆向而抓取到我们想要的信息,但如果是大量的信息的话,速度上面也许会慢一些。总之,各有利弊。