Python爬虫三-用selenium+pyquery+mongodb来爬取淘宝美食

1.流程框架

淘宝页面信息很复杂的,含有各种请求参数和加密参数,如果直接请求或者分析Ajax请求的话会很繁琐。所以我们可以用Selenium来驱动浏览器模拟点击来爬取淘宝的信息。用Selenium爬取可以直接获取网页渲染后的源代码,输出page_source属性即可。这样,我们就可以做到网页的动态爬取了。缺点是速度相比之下比较慢。

2.环境须知

在进行爬取之前,需进行的准备工作是安装好selenium库,以及pyquery,mongodb,PhantomJS。浏览器我用的是Chrome,为了在python环境下驱动,又安装了ChromeDriver。简单介绍一下selenium库的作用及安装过程。

1)selenium库的作用

selenium是一套完整的web应用程序测试系统,包含了测试的录制(selenium IDE),编写及运行(Selenium Remote Control)和测试的并行处理(Selenium Grid)。Selenium的核心Selenium Core基于JsUnit,完全由JavaScript编写,因此可以用于任何支持JavaScript的浏览器上。selenium可以模拟真实浏览器,自动化测试工具,支持多种浏览器,爬虫中主要用来解决JavaScript渲染问题。

这里要说一下比较重要的PhantomJS,PhantomJS是一个而基于WebKit的服务端JavaScript API,支持Web而不需要浏览器支持,其快速、原生支持各种Web标准:Dom处理,CSS选择器,JSON等等。PhantomJS可以用用于页面自动化、网络监测、网页截屏,以及无界面测试。

2)安装

pip install selenium 或者到https://pypi.python.org/pypi/selenium 下载setup安装包,之后进入目录后运行python setup.py install。

3.完整代码

由于Chrome版浏览器会一直跳出,所以本文使用的是PhantomJS版。

config.py文件

MONGO_URL = 'localhost'

MONGO_DB = 'taobao'

MONGO_TABLE = 'product'

SERVICE_ARGS = ['--load-images=false','--disk-cache=true']#不加载图片,开启缓存

KEYWORD = "美食"

spider.py文件

importre

fromseleniumimportwebdriver

fromselenium.webdriver.common.byimportBy

fromselenium.webdriver.support.uiimportWebDriverWait

fromselenium.webdriver.supportimportexpected_conditionsasEC

frompyqueryimportPyQueryaspq

fromconfig2import*

importpymongo

client = pymongo.MongoClient(MONGO_URL)

db = client[MONGO_DB]

browser = webdriver.PhantomJS(service_args=SERVICE_ARGS)

wait = WebDriverWait(browser,10)#浏览器最长等待10秒

browser.set_window_size(1400,900)

defsearch():#搜索方法

print("正在搜索")

try:

browser.get("https://www.taobao.com")

input= wait.until(

EC.presence_of_element_located((By.CSS_SELECTOR,"#q"))

)

submit = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR,'#J_TSearchForm > div.search-button > button')))

input.send_keys(KEYWORD)#向输入框输入“美食”

submit.click()#点击按钮

get_product()#调用get_product()函数获取商品信息

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

returntotal.text#返回total的内容

exceptTimeoutError:

returnsearch()

defnext_page(page_number):#翻页方法

print("正在翻页")

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()

get_product()#调用get_product()函数获取商品信息

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)))

#获取当前页码并判定

exceptTimeoutError:

next_page(page_number)#出错则重新调用

defget_product():#获取商品信息方法

wait.until(EC.presence_of_element_located((By.CSS_SELECTOR,"#mainsrp-itemlist .items .item")))#获取商品信息标签

html = browser.page_source#获取网页源代码

doc = pq(html)#使用pyquery库解析

items = doc("#mainsrp-itemlist .items .item").items()#获取所有item标签

foriteminitems:

product = {#以字典形式保存数据

'image': item.find('.pic .img').attr('src'),#图片链接

'price': item.find('.price').text(),#价格

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

'title': item.find('.title').text(),

'shop': item.find('.shop').text(),

'location': item.find('.location').text()

}

print(product)#输出商品信息

save_to_mongo(product)#把商品信息存储到数据库

defsave_to_mongo(result):#保存到数据库的方法

try:

ifdb[MONGO_TABLE].insert(result):#把数据插入到数据库

print("存储到MONGODB成功",result)

exceptException:

print("存储到MONGODB失败",result)

defmain():#主方法

try:

total = search()

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

"""

result = re.compile("(\d+)")#得到数字

total = re.search(result,total).group(1)

#re.search扫描整个字符串并返回第一个成功的匹配

#因为正则里使用了(),所以使用group()获取

total = int(total)#可能是字符串,强制类型转换

"""

foriinrange(2,total +1):

next_page(i)#从2到100页翻页

print(total)

exceptException:

print("出错了.")

finally:

browser.close()#关闭浏览器

if__name__ =="__main__":

main()

代码分享完毕。使用Selenium中,记得在关键操作前加入等待判定,确保所需元素加载完成或者达到我们想要的状态。

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20181121G1SLOC00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 yunjia_community@tencent.com 删除。

扫码关注云+社区

领取腾讯云代金券