selenium+chrome抓取淘宝宝贝-崔庆才思路

站点分析

  • 看了交互,好复杂
  • 看了下Ajax,好复杂
  • 看了下其他内容,看不懂...

所以,没啥好分析的,直接上selenium吧

源码及遇到的问题

在搜索时,会跳转到登录界面

这个没有办法,是淘宝的反爬虫机制. 因为通过selenium webdriver调用的浏览器会有很多异于正常浏览器的参数,具体生成了啥参数,咱也没看懂.

具体的可以参考下面这个大姐的文章

分析淘宝登陆对selenium爬虫的封杀方案,反爬虫机制的升级

而且阿里不愧是阿里,哪怕webdriver调用的chrome中输入用户名和密码依旧不可以.

网上查了一下,基本是selenium是被封的死死的,基本上比较靠谱的方法就是使用pyppeteer库.

那么问题来了...

  1. 我这次就是玩selenium的,临阵换库,不好.

好了,总结了这么多,最终,发现了淘宝的一个bug. 虽然用户名密码登录的方式会由于ua值校验等问题被拒绝. 但是扫码登录不会...

所以我的解决思路很土,先扫码登录,拿到cookie,然后调用chrome之前,先把cookie写进去. (注意!这里有个坑,很大的坑) 如果不出意外的话,应该是可以的.

step1:干起来! 先取cookie

  1. def get_taobao_cookies():


  2. url = ‘https://www.taobao.com/‘ 

  3. browser.get(‘https://login.taobao.com/‘) 

  4. while True: 

  5. print("please login to Taobao!") 

  6. # 这里等一下下 

  7. time.sleep(4) 

  8. # 等到界面跳转到首页之后,下手 

  9. while browser.current_url == url: 

  10. tbCookies = browser.get_cookies() 

  11. browser.quit() 

  12. output_path = open(‘taobaoCookies.pickle‘, ‘wb‘) 

  13. pickle.dump(tbCookies, output_path) 

  14. output_path.close() 

  15. return tbCookies 



知识补充:pickle模块


python的pickle模块实现了基本的数据序列和反序列化。

通过pickle模块的序列化操作我们能够将程序中运行的对象信息保存到文件中去,永久存储。

通过pickle模块的反序列化操作,我们能够从文件中创建上一次程序保存的对象。

基本接口:

pickle.dump(obj, file, [,protocol])

有了 pickle 这个对象, 就能对 file 以读取的形式打开:

x = pickle.load(file)

取cookie倒是没什么问题. 问题是,这是我第一次见到原始的cookie,有点懵. 仔细看了之后才搞懂:

  • 取出的cookie是一个数组
  • 数组的每个元素是一个cookie
  • 每个cookie又是一个字典,其中记录这这个cookie的 domian,key,value,path等等属性.

这里我用pickle.dump()方法把cookie存储下来了. 下次使用的时候,直接load一下就好了.

step2:载入cookie

载入的话分为两部分:

第一部分:从文件中读取cookie

这个很简单,不做过多描述

  1. def read_taobao_cookies():


  2. if os.path.exists(‘taobaoCookies.pickle‘): 

  3. read_path = open(‘taobaoCookies.pickle‘, ‘rb‘) 

  4. tbCookies = pickle.load(read_path) 

  5. else: 

  6. tbCookies = get_taobao_cookies() 

  7. return tbCookies 


第二部分:讲cookie载入chrome

这个可把我坑惨了.

先看代码,在search()方法中定义了如何载入cookie

  1. cookies = read_taobao_cookies()


  2. # add_cookie之前要先打开一下网页,不然他妈的会报invalid domain错误. 日了狗了 

  3. browser.get(‘https://www.taobao.com‘) 

  4. for cookie in cookies: 

  5. # stackoverflow查到的,不知道为啥,要把expiry这个键值对删掉,不然的话,会报invalid argument,MD! 

  6. if ‘expiry‘ in cookie: 

  7. del cookie[‘expiry‘] 

  8. browser.add_cookie(cookie) 


这里需要注意的有两点:

  1. 在调用add_cookie()方法之前,必须先打开一个网页.不然的话就会报InvalidCookieDomainException 的错误.
  2. cookie中的‘expiry‘属性要删除,不然会报invalid argument: invalid ‘expiry‘

但是看了下API,add_cookie()是支持这个expiry这个参数的

后来查了一下,当前chromedriver对于expiry只支持int64,不支持double. 据说是chromedriver的一个bug,在后续版本中会修复.

详细回答参见这个问题下的高票答案

关于add_cookie时,expiry参数报错的问题

step3:放飞自我

这两个问题解决了之后,基本上剩下的都不是什么大问题了. 这里说一个之前不知道的小技巧,chrome浏览器在源码审查的时候,可以选中页面元素,直接右键复制CSS选择器

这个功能还挺好使的. 表示之前并不知道...

Chrome的CSS选择器

关于phantomJS浏览器的问题

在使用selenium的时候,如果不想看到浏览器界面,可是使用 phantomJS这个无界面的浏览器来代替. 但是看到pycharm报了个warning. 说是phantomJS已经被depressed. 建议使用headless chrome替代.

于是看了一眼headless chrome怎么用. 很简单,在调用chrome的时候传入一个参数即可.

  1. chrome_options = Options()


  2. chrome_options.add_argument(‘--headless‘) 

  3. browser = webdriver.Chrome(options=chrome_options) 


源码

源码已上传github,有需要的请直接下载.

  1. import os


  2. import pickle 

  3. import re 

  4. import time 


  5. from pyquery import PyQuery as pq 

  6. from selenium import webdriver 

  7. from selenium.common.exceptions import TimeoutException 

  8. from selenium.webdriver.common.by import By 

  9. from selenium.webdriver.support import expected_conditions as EC 

  10. from selenium.webdriver.support.ui import WebDriverWait 

  11. import pymongo 

  12. from config import * 


  13. #连接数据库 

  14. client = pymongo.MongoClient(MONGO_URL) 

  15. db = client[MONGO_DB] 


  16. # 创建Chrome对象 

  17. browser = webdriver.Chrome() 

  18. wait = WebDriverWait(browser, 10) 


  19. def get_taobao_cookies(): 

  20. url = ‘https://www.taobao.com/‘ 

  21. browser.get(‘https://login.taobao.com/‘) 

  22. while True: 

  23. print("please login to Taobao!") 

  24. time.sleep(4) 

  25. while browser.current_url == url: 

  26. tbCookies = browser.get_cookies() 

  27. browser.quit() 

  28. output_path = open(‘taobaoCookies.pickle‘, ‘wb‘) 

  29. pickle.dump(tbCookies, output_path) 

  30. output_path.close() 

  31. return tbCookies 


  32. def read_taobao_cookies(): 

  33. if os.path.exists(‘taobaoCookies.pickle‘): 

  34. read_path = open(‘taobaoCookies.pickle‘, ‘rb‘) 

  35. tbCookies = pickle.load(read_path) 

  36. else: 

  37. tbCookies = get_taobao_cookies() 

  38. return tbCookies 


  39. def search(): 

  40. try: 

  41. # 直接调用get()方法不行了,淘宝有反爬虫机制,所以要先传一个cookies进去 

  42. # browser.get(‘https://www.taobao.com‘) 

  43. cookies = read_taobao_cookies() 

  44. # add_cookie之前要先打开一下网页,不然他妈的会报invalid domain错误. 日了狗了 

  45. browser.get(‘https://www.taobao.com‘) 

  46. for cookie in cookies: 

  47. # stackoverflow查到的,不知道为啥,要把expiry这个键值对删掉,不然的话,会报invalid argument,MD! 

  48. if ‘expiry‘ in cookie: 

  49. del cookie[‘expiry‘] 

  50. browser.add_cookie(cookie) 

  51. browser.get(‘https://www.taobao.com‘) 

  52. input_text = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, ‘#q‘))) 

  53. submit = wait.until( 

  54. EC.element_to_be_clickable((By.CSS_SELECTOR, ‘#J_TSearchForm > div.search-button > button‘))) 

  55. input_text.send_keys(KEYWORD) 

  56. submit.click() 

  57. total = wait.until( 

  58. EC.presence_of_element_located((By.CSS_SELECTOR, ‘#mainsrp-pager > div > div > div > div.total‘))) 

  59. get_products() 

  60. return total.text 

  61. except TimeoutException: 

  62. # 注意这是个递归,如果超时的话,就再请求一次 

  63. return search() 


  64. def next_page(page_number): 

  65. try: 

  66. input_text = wait.until( 

  67. EC.presence_of_element_located((By.CSS_SELECTOR, ‘#mainsrp-pager > div > div > div > div.form > input‘))) 

  68. submit = wait.until(EC.element_to_be_clickable( 

  69. (By.CSS_SELECTOR, ‘#mainsrp-pager > div > div > div > div.form > span.btn.J_Submit‘))) 

  70. input_text.clear() 

  71. input_text.send_keys(page_number) 

  72. submit.click() 

  73. wait.until(EC.text_to_be_present_in_element( 

  74. (By.CSS_SELECTOR, ‘#mainsrp-pager > div > div > div > ul > li.item.active > span‘), str(page_number))) 

  75. get_products() 

  76. except TimeoutException: 

  77. return next_page(page_number) 


  78. def get_products(): 

  79. wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, ‘#mainsrp-itemlist .items .item‘))) 

  80. html = browser.page_source 

  81. doc = pq(html) 

  82. items = doc(‘#mainsrp-itemlist .items .item‘).items() 

  83. for item in items: 

  84. product = { 

  85. # 不知道为什么,取src的话,会出现一些s.gif的链接,所以改取原始图片 

  86. ‘image‘: item.find(‘.pic .img‘).attr(‘data-src‘), 

  87. ‘price‘: item.find(‘.price‘).text(), 

  88. ‘deal‘: item.find(‘.deal-cnt‘).text()[:-3], 

  89. ‘title‘: item.find(‘.title‘).text(), 

  90. ‘shop‘: item.find(‘.shop‘).text(), 

  91. ‘location‘: item.find(‘.location‘).text() 



  92. save_to_mongo(product) 


  93. def save_to_mongo(result): 

  94. try: 

  95. if db[MONGO_TABLE].insert(result): 

  96. print(‘存储到MONGODB成功:‘,result) 

  97. except Exception: 

  98. print(‘存储到MONGODB失败‘,result) 


  99. def main(): 

  100. try: 

  101. total = search() 

  102. total = int(re.compile(‘(\d+)‘).search(total).group(1)) 

  103. for i in range(2, total + 1): 

  104. next_page(i) 

  105. except Exception as exp: 

  106. print(‘出错啦‘,exp) 

  107. finally: 

  108. browser.close() 


  109. if __name__ == ‘__main__‘: 

  110. main() 



吾码2016


原文地址:https://www.cnblogs.com/thecatcher/p/12313759.html

时间: 2024-11-07 14:56:03

selenium+chrome抓取淘宝宝贝-崔庆才思路的相关文章

selenium抓取淘宝数据报错:warnings.warn('Selenium support for PhantomJS has been deprecated, please use headless

ssh://[email protected]:22/root/anaconda3/bin/python3 -u /www/python3/maoyantop100/meishi_selenium.py /root/anaconda3/lib/python3.6/site-packages/selenium/webdriver/phantomjs/webdriver.py:49: UserWarning: Selenium support for PhantomJS has been depre

使用selenium模拟浏览器抓取淘宝信息

通过Selenium模拟浏览器抓取淘宝商品美食信息,并存储到MongoDB数据库中. 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.webdri

Python爬虫实战四之抓取淘宝MM照片

福利啊福利,本次为大家带来的项目是抓取淘宝MM照片并保存起来,大家有没有很激动呢? 最新动态 更新时间:2015/8/2 最近好多读者反映代码已经不能用了,原因是淘宝索引页的MM链接改了.网站改版了,URL的索引已经和之前的不一样了,之前可以直接跳转到每个MM的个性域名,现在中间加了一个跳转页,本以为可以通过这个页面然后跳转到原来的个性域名,而经过一番折腾发现,这个跳转页中的内容是JS动态生成的,所以不能用Urllib库来直接抓取了,本篇就只提供学习思路,代码不能继续用了. 之后博主会利用其它方

芝麻HTTP:Python爬虫实战之抓取淘宝MM照片

本篇目标 1.抓取淘宝MM的姓名,头像,年龄 2.抓取每一个MM的资料简介以及写真图片 3.把每一个MM的写真图片按照文件夹保存到本地 4.熟悉文件保存的过程 1.URL的格式 在这里我们用到的URL是 http://mm.taobao.com/json/request_top_list.htm?page=1,问号前面是基地址,后面的参数page是代表第几页,可以随意更换地址.点击开之后,会发现有一些淘宝MM的简介,并附有超链接链接到个人详情页面. 我们需要抓取本页面的头像地址,MM姓名,MM年

【Python】抓取淘宝数据库月报,发送邮件,本地存档,保存元信息

用途 定期抓取淘宝数据库月报 发送邮件,保存到本地,最好是git中 发送元数据到mysql中,后期可以做成接口集成到运维平台中,便于查询 使用方式 # 下载(必须) cd ~ && git clone https://github.com/naughtyGitCat/spider_taobao_mysql.git # 修改配置(必须) vim config.py # 安装crontab(可选) "0 10 8 * * source ~/.bashrc && pyt

前端 抓取淘宝的产品 上架到拼多多

这里只是简单实现,因为时间比较急. 主要解决的问题是,淘宝的那款产品分类很多,拼多多一个一个添加分类太累了,受不了. 还有就是拼多多要求每个分类都必须有图片,这也是坑的一笔. 主要是js实现 抓取淘宝的分类 得到淘宝的分类数组: var arr = []; $("ul.J_TSaleProp li a span").each(function (index) { var item = $("ul.J_TSaleProp li a span")[index]; var

python爬取ajax动态生成的数据 以抓取淘宝评论为例子

在学习python的时候,一定会遇到网站内容是通过ajax动态请求.异步刷新生成的json数据的情况,并且通过python使用之前爬取静态网页内容的方式是不可以实现的,所以这篇文章将要讲述如果在python中爬取ajax动态生成的数据. 至于读取静态网页内容的方式,有兴趣的可以查看博客内容. 这里我们以爬取淘宝评论为例子讲解一下如何去做到的. 这里主要分为了四步: 一 获取淘宝评论时,ajax请求链接(url) 二 获取该ajax请求返回的json数据 三 使用python解析json数据 四

selenium抓取淘宝商品

我们知道,javascript动态渲染页面不止ajax这一种,有些网站可能整个都是由javascript渲染后生成的,还有些网站,比如淘宝,它虽然有ajax请求,但其中加入了很多复杂的参数,需要耗费大量时间才能找出规律,这时候,我们就可以用selenium,它可以直接模仿浏览器运行,并且抓取在运行时的源码,不用管ajax那些复杂的数,此次我们使用一种无界面的浏览器PhantomJS,它可以做到不用打开浏览器就可以运行,另外,需要正确安装好Selenium库. #我们需要用到MongoDB数据库,

使用Selenium模拟浏览器抓取淘宝商品美食信息

淘宝页面比较复杂,含有各种请求参数和加密参数,如果直接请求或者分析Ajax将会非常繁琐.Selenium是一个自动化测试工具,可以驱动浏览器去完成各种工作,比如模拟点击.输入和下拉等多种功能,这样我们只需关心操作,不需要关心后台发生了怎么样的请求下面对具体操作步骤进行详述. 创建webdriver对象 #创建一个WebDriver对象 from Selenium import webdriver browser = webdriver.Chrome() 大多数网络应用程序都使用AJAX技术.当浏