最近更新:2018-02-11
1.相关工具介绍
2.目标站点分析
3.流程框架及准备工作
4.爬虫步骤
学习参考链接:
Python3网络爬虫开发实战 7.1-Selenium的使用
Python3网络爬虫开发实战 7.4-使用Selenium爬取淘宝商品
1.相关工具介绍
- Selenium是一个自动化测试工具,利用它可以驱动浏览器执行特定的动作,如点击、下拉等操作,同时还可以获取浏览器当前呈现的页面的源代码,做到可见即可爬。对于一些JavaScript动态渲染的页面来说,此种抓取方式非常有效。
- PhanttomJS是无界面浏览器,因为老是开着浏览器,不方便.
- Chrome是个浏览器
2.目标站点分析
本节中,我们要利用Selenium抓取淘宝商品并用pyquery解析得到商品的图片、名称、价格、购买人数、店铺名称和店铺所在地信息,并将其保存到MongoDB。
- 打开淘宝网:https://www.taobao.com/
- 搜索一个关键词:美食,看到非常好多吃的,我们现在就是要爬取这些内容.
-
打开淘宝页面,搜索商品,比如美食,此时打开开发者工具,截获Ajax请求,我们可以发现获取商品列表的接口,如图7-19所示。但是这个Ajax接口包含几个参数,参数不能直接发现其规律,如果要去探寻它的生成规律,也不是做不到,但这样相对会比较烦琐,所以如果直接用Selenium来模拟浏览器的话,就不需要再关注这些接口参数了,只要在浏览器里面可以看到的,都可以爬取。这也是我们选用Selenium爬取淘宝的原因
- 爬取的顺序是:需要模拟在输入框输入关键词,点击搜索按钮,获取首页的内容,模拟点击翻页,获得每页源代码,并分析商品信息,存储到MongoDB数据库.
3.流程框架及准备工作
3.1流程框架
3.2准备工作
本节中,我们首先以Chrome为例来讲解Selenium的用法。在开始之前,请确保已经正确安装好Chrome浏览器并配置好了ChromeDriver;另外,还需要正确安装Python的Selenium库;最后,还对接了PhantomJS和Firefox,请确保安装好PhantomJS和Firefox并配置好了GeckoDriver。如果环境没有配置好,可参考如下崔庆才的博客链接。
Python3网络爬虫开发实战4.3-使用pyquery
Python3网络爬虫开发实战1.5.2-PyMongo的安装
Python3网络爬虫开发实战1.4.2-MongoDB安装
Python3网络爬虫开发实战1.3.3-pyquery的安装
Python3网络爬虫开发实战1.2.5-PhantomJS的安装
Python3网络爬虫开发实战1.2.3-ChromeDriver的安装
Python3网络爬虫开发实战 1.2.2-Selenium的安装
4.爬虫步骤
4.1声明浏览器对象
4.1.1本次案例声明浏览器方法
from selenium import webdriver
browser = webdriver.Chrome()
Chrome浏览器会自动打开,如下截图,则说明驱动Chrome浏览器成功:
4.1.2声明浏览器拓展学习内容
Selenium支持非常多的浏览器,如Chrome、Firefox、Edge等,还有Android、BlackBerry等手机端的浏览器。另外,也支持无界面浏览器PhantomJS。
此外,我们可以用如下方式初始化:
browser = webdriver.Chrome()
browser = webdriver.Firefox()
browser = webdriver.Edge()
browser = webdriver.PhantomJS()
browser = webdriver.Safari()
这样就完成了浏览器对象的初始化并将其赋值为browser对象。接下来,我们要做的就是调用browser对象,让其执行各个动作以模拟浏览器操作。
4.2定义搜索的方法
4.2.1定义搜索的方法-search()
- 这里首先构造了一个WebDriver对象,使用的浏览器是Chrome,然后指定一个关键词,如美食.
- 等待加载时,我们使用了WebDriverWait对象,它可以指定等待条件,同时指定一个最长等待时间,这里指定为最长10秒。如果在这个时间内成功匹配了等待条件,也就是说页面元素成功加载出来了,就立即返回相应结果并继续向下执行,否则到了最大等待时间还没有加载出来时,就直接抛出超时异常。
- 比如,我们最终要等待商品信息加载出来,就指定了presence_of_element_located这个条件,然后传入了#q这个选择器,而这个选择器对应的内容就是搜索商品的输入框.
- 关于搜索美食操作,这里首先获取商品输入框,赋值为input,然后获取“确定”按钮,赋值为submit.
- 调用send_keys()方法将美食填充到输入框中,然后点击“确定”按钮(submit.click())即可。
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
browser = webdriver.Chrome()
wait = WebDriverWait(browser, 10)
def search():
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("美食") #操作动作
submit.click()
def main():
search()
if __name__=='__main__':
main()
4.2.2selenium的拓展学习内容
- 官方学习资料:Selenium with Python
- Python3网络爬虫开发实战7.1-Selenium的使用
- 显式等待
这里还有一种更合适的显式等待方法,它指定要查找的节点,然后指定一个最长等待时间。如果在规定时间内加载出来了这个节点,就返回查找的节点;如果到了规定时间依然没有加载出该节点,则抛出超时异常。示例如下:
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
browser = webdriver.Chrome()
browser.get('https://www.taobao.com/')
wait = WebDriverWait(browser, 10)
input = wait.until(EC.presence_of_element_located((By.ID, 'q')))
button = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, '.btn-search')))
print(input, button)
这里首先引入WebDriverWait这个对象,指定最长等待时间,然后调用它的until()方法,传入要等待条件expected_conditions。比如,这里传入了presence_of_element_located这个条件,代表节点出现的意思,其参数是节点的定位元组,也就是ID为q的节点搜索框。
这样可以做到的效果就是,在10秒内如果ID为q的节点(即搜索框)成功加载出来,就返回该节点;如果超过10秒还没有加载出来,就抛出异常。
对于按钮,可以更改一下等待条件,比如改为element_to_be_clickable,也就是可点击,所以查找按钮时查找CSS选择器为.btn-search的按钮,如果10秒内它是可点击的,也就是成功加载出来了,就返回这个按钮节点;如果超过10秒还不可点击,也就是没有加载出来,就抛出异常。
运行代码,在网速较佳的情况下是可以成功加载出来的。
4.3获取总页面的页数内容-research()
4.3.1本次案例模拟翻页的方法
- 首先获取页数有多少页,点击美食搜索之后,下一步肯定是要等待页数加载出来,需要再加一个等待的判断,即
-
那么,怎样知道有没有跳转到对应的页码呢?我们可以注意到,成功跳转某一页后,页码都会高亮显示,如图7-25所示。total=wait.until(EC.presence_of_element_located((By.CSS_SELECTOR,"#mainsrp-pager > div > div > div > div.total")))
这里商品的搜索结果一般最大都为100页,要获取每一页的内容,只需要将页码从1到100顺序遍历即可,页码数是确定的。所以,直接在页面跳转文本框中输入要跳转的页码,然后点击“确定”按钮即可跳转到页码对应的页面。
- 使用wait时间过久会出现异常.因此增加try and except:
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
browser = webdriver.Chrome()
wait = WebDriverWait(browser, 10)
def search():
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("美食") #操作动作
submit.click()
total = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR,"#mainsrp-pager > div > div > div > div.total")))
return total.text#返回内容
except TimeoutException:
return search()
def main():
total=search()
print(total)
if __name__=='__main__':
main()
最终显示的结果:
- 需要用正则表达式提取100
total=search()
total=int(re.compile('(\d+)').search(total).group(1))#打印出来可能是个字符串,所以要转义为整数
import re
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
browser = webdriver.Chrome()
wait = WebDriverWait(browser, 10)
def search():
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("美食") #操作动作
submit.click()
total = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR,"#mainsrp-pager > div > div > div > div.total")))
return total.text#返回内容
except TimeoutException:
return search()
def main():
total=search()
total=int(re.compile('(\d+)').search(total).group(1))
print(total)
if __name__=='__main__':
main()
最终显示的结果:
4.3.2获得总页面页数的学习内容
-
获取SELECTOR的目标值方法
4.4循环-遍历每页-next_page(page_number)
-刚才我们所定义的next_page(page_number)方法需要接收参数page,page代表页码。这里我们实现页码遍历即可.
- 其实现非常简单,只需要调用一个for循环即可。这里定义最大的页码数为100,range()方法的返回结果就是1到100的列表,顺序遍历,调用next_page(page_number)方法即可。
- 这样我们的淘宝商品爬虫就完成了,最后调用main()方法即可运行。
4.4.1本次循环的方法
1)首先查看淘宝页面,使用页面跳转的方法有两种,一是使用高亮的第1页,第2页,....下一页,而是直接输入第几页
-方法一 ,不推荐使用,具体原因如下:
这里不直接点击“下一页”的原因是:一旦爬取过程中出现异常退出,比如到50页退出了,此时点击“下一页”时,就无法快速切换到对应的后续页面了。此外,在爬取过程中,也需要记录当前的页码数,而且一旦点击“下一页”之后页面加载失败,还需要做异常检测,检测当前页面是加载到了第几页。整个流程相对比较复杂,所以这里我们直接用跳转的方式来爬取页面。
-
方法二,使用的方式是,直接在页面上写第几页.
2)页面输入框
input = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, "#mainsrp-pager > div > div > div > div.form > input")))
3)页面确定按钮
submit = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR,"#mainsrp-pager > div > div > div > div.form > span.btn.J_Submit")))
4)首先清除页面输入框的内容:
input.clear()#清除页码输入框的内容
完整的代码:
def next_page(page_number):
print("正在翻页",page_number)
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()
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)))#判断是否翻页成功,通过判断当前的页数是否正确
get_product()
except TimeoutException:
next_page(page_number)
4.5解析网页-商品列表-get_products()
- 接下来,我们就可以实现get_products()方法来解析商品列表了。这里我们直接获取页面源代码,然后用pyquery进行解析
- 首先,调用page_source属性获取页码的源代码,然后构造了PyQuery解析对象,接着提取了商品列表,此时使用的CSS选择器是#mainsrp-itemlist .items .item,它会匹配整个页面的每个商品。它的匹配结果是多个,所以这里我们又对它进行了一次遍历,用for循环将每个结果分别进行解析,每次循环把它赋值为item变量,每个item变量都是一个PyQuery对象,然后再调用它的find()方法,传入CSS选择器,就可以获取单个商品的特定内容了。
- 可以发现,它是一个img节点,包含id、class、data-src、alt和src等属性。这里之所以可以看到这张图片,是因为它的src属性被赋值为图片的URL。把它的src属性提取出来,就可以获取商品的图片了。不过我们还注意data-src属性,它的内容也是图片的URL,观察后发现此URL是图片的完整大图,而src是压缩后的小图,所以这里抓取data-src属性来作为商品的图片。
- 因此,我们需要先利用find()方法找到图片的这个节点,然后再调用attr()方法获取商品的data-src属性,这样就成功提取了商品图片链接。然后用同样的方法提取商品的价格、成交量、名称、店铺和店铺所在地等信息,接着将所有提取结果赋值为一个字典product,随后调用save_to_mongo()将其保存到MongoDB即可。
- 保存到MongoDB
4.5.1本次解析的方法
-
商品的代码结构,如下:
-
判断页面商品信息是否加载成功
wait.until(EC.presence_of_element_located((By.CSS_SELECTOR,"#mainsrp-itemlist .items .item "))) -
获得页面所有选择的内容:
items=doc('#mainsrp-itemlist .items .item').items() -
分析商品图片:
"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()
-完整的代码:
# -*- coding: utf-8 -*-
"""
Created on Sat Feb 10 18:33:26 2018
@author: Administrator
"""
import re
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from pyquery import PyQuery as pq
browser = webdriver.Chrome()
wait = WebDriverWait(browser, 10)
def search():
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("美食") #操作动作
submit.click()
total = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR,"#mainsrp-pager > div > div > div > div.total")))
get_product()
return total.text#返回内容
except TimeoutException:
return search()
def next_page(page_number):
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()
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)))#判断是否翻页成功,通过判断当前的页数是否正确
get_product()
except TimeoutException:
next_page(page_number)
def get_product():
wait.until(EC.presence_of_element_located((By.CSS_SELECTOR,"#mainsrp-itemlist .items .item")))#判断商品信息是否加载成功
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("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)
def main():
total=search()
total=int(re.compile('(\d+)').search(total).group(1))
for i in range(2,total+1):
next_page(i)
if __name__=='__main__':
main()
-最后显示的结果
4.5.2解析的学习内容
4.6保存在MongoDB
这里首先创建了一个MongoDB的连接对象,然后指定了数据库,随后指定了Collection的名称,接着直接调用insert()方法将数据插入到MongoDB。此处的result变量就是在get_products()方法里传来的product,包含单个商品的信息。
4.6.1本次保存在MongoDB的方法
- 新建一个配置文件叫untitled2.py,并输入以下代码
MONGO_URL ="localhost"#本地数据库
MONGO_DB="taobao"#数据库的名称
MONGO_TABLE="product"#数据库表的名称
- 在之前的文件引入mongodb相关数据
import re
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from pyquery import PyQuery as pq
from untitled2 import *#引入mongodb的配置文件
import pymongo#引入mongodb所有的变量
- 在之前的文件声明mongodb相关信息
client=pymongo.MongoClient(MONGO_URL)
db=client[MONGO_DB]
- 在之前的文件定义mongodb方法:
def save_to_mongo(result):
try:
if db[MONGO_TABLE].insert(result):
print("存储到MONGODB成功",result)
except Exception:
print("存储到MONGODB失败",result)
- 完整的代码为:
import re
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from pyquery import PyQuery as pq
from untitled2 import *#引入mongodb的配置文件
import pymongo
client=pymongo.MongoClient(MONGO_URL)
db=client[MONGO_DB]
browser = webdriver.Chrome()
wait = WebDriverWait(browser, 10)
def search():
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("美食") #操作动作
submit.click()
total = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR,"#mainsrp-pager > div > div > div > div.total")))
get_product()
return total.text#返回内容
except TimeoutException:
return search()
def next_page(page_number):
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()
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)))#判断是否翻页成功,通过判断当前的页数是否正确
get_product()
except TimeoutException:
next_page(page_number)
def get_product():
wait.until(EC.presence_of_element_located((By.CSS_SELECTOR,"#mainsrp-itemlist .items .item")))#判断商品信息是否加载成功
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("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)
def save_to_mongo(result):
try:
if db[MONGO_TABLE].insert(result):
print("存储到MONGODB成功",result)
except Exception:
print("存储到MONGODB失败",result)
def main():
total=search()
total=int(re.compile('(\d+)').search(total).group(1))
for i in range(2,total+1):
next_page(i)
browser.close()#把浏览器关掉
if __name__=='__main__':
main()
配置文件
MONGO_URL ="localhost"
MONGO_DB="taobao"
MONGO_TABLE="product"
运行的时候,同时要将配置文件打开,才可以运行.运行的结果如下:
4.6.2MongoDB的学习内容
4.7使用PhantomJS
4.7.1本次使用PhantomJS的方法
- 因用模拟浏览器打开,有点麻烦,所以改为用PhanttomJS,,是无界面浏览器.
将browser = webdriver.Chrome()改为browser = webdriver.PhantomJS() - 在untitled2.py配置文件增加:
SERVICE_ARGS=["--load-images=false","--disk-cache=true"]#是数组形式,不加载浏览器图片,开启缓存 - 在之前文件,增加配置文的变量引入:
browser = webdriver.PhantomJS(service_args=SERVICE_ARGS) - 分别在search()/next_page(page_number)分别增加print("正在搜索")/print("正在翻页",page_number)
- 完整的代码为:
# -*- coding: utf-8 -*-
"""
Created on Sat Feb 10 18:33:26 2018
@author: Administrator
"""
import re
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from pyquery import PyQuery as pq
from untitled2 import *#引入mongodb的配置文件
import pymongo
client=pymongo.MongoClient(MONGO_URL)
db=client[MONGO_DB]
browser = webdriver.PhantomJS(service_args=SERVICE_ARGS)
wait = WebDriverWait(browser, 10)
browser.set_window_size(1400,900)#设置窗口大小
def search():
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("美食") #操作动作
submit.click()
total = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR,"#mainsrp-pager > div > div > div > div.total")))
get_product()
return total.text#返回内容
except TimeoutException:
return search()
def next_page(page_number):
print("正在翻页",page_number)
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()
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)))#判断是否翻页成功,通过判断当前的页数是否正确
get_product()
except TimeoutException:
next_page(page_number)
def get_product():
wait.until(EC.presence_of_element_located((By.CSS_SELECTOR,"#mainsrp-itemlist .items .item")))#判断商品信息是否加载成功
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("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)
def save_to_mongo(result):
try:
if db[MONGO_TABLE].insert(result):
print("存储到MONGODB成功",result)
except Exception:
print("存储到MONGODB失败",result)
def main():
total=search()
total=int(re.compile('(\d+)').search(total).group(1))
for i in range(2,total+1):
next_page(i)
browser.close()#把浏览器关掉
if __name__=='__main__':
main()
配置文件代码为:
MONGO_URL ="localhost"
MONGO_DB="taobao"
MONGO_TABLE="product"
SERVICE_ARGS=["--load-images=false","--disk-cache=true"]#是数组形式,不加载浏览器图片,开启缓存
运行的时候,同时要将配置文件打开,才可以运行.运行的结果如下:
4.7.2使用PhantomJS的方法
官方网站:PhantomJS
4.8整体代码的完善
4.7.1本次完善代码的方法
- 在untitled2.py配置文件增加:KEYWORD = "美食"
然后将search()中的input.send_keys("美食")改为input.send_keys("KEYWORD") - 将main(),增加try 和findally
def main():
try:
total=search()
total=int(re.compile('(\d+)').search(total).group(1))
for i in range(2,total+1):
next_page(i)
finally:
browser.close()#把浏览器关掉
完整的代码
@author: Administrator
"""
import re
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.webdriver.support import expected_conditions as EC
from pyquery import PyQuery as pq
from untitled2 import *#引入mongodb的配置文件
import pymongo
client=pymongo.MongoClient(MONGO_URL)
db=client[MONGO_DB]
browser = webdriver.PhantomJS(service_args=SERVICE_ARGS)
wait = WebDriverWait(browser, 10)
browser.set_window_size(1400,900)#设置窗口大小
def search():
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()
total = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR,"#mainsrp-pager > div > div > div > div.total")))
get_product()
return total.text#返回内容
except TimeoutException:
return search()
def next_page(page_number):
print("正在翻页",page_number)
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()
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)))#判断是否翻页成功,通过判断当前的页数是否正确
get_product()
except TimeoutException:
next_page(page_number)
def get_product():
wait.until(EC.presence_of_element_located((By.CSS_SELECTOR,"#mainsrp-itemlist .items .item")))#判断商品信息是否加载成功
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("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)
def save_to_mongo(result):
try:
if db[MONGO_TABLE].insert(result):
print("存储到MONGODB成功",result)
except Exception:
print("存储到MONGODB失败",result)
def main():
try:
total=search()
total=int(re.compile('(\d+)').search(total).group(1))
for i in range(2,total+1):
next_page(i)
finally:
browser.close()#把浏览器关掉
if __name__=='__main__':
main()
配置文件:
MONGO_URL ="localhost"
MONGO_DB="taobao"
MONGO_TABLE="product"
SERVICE_ARGS=["--load-images=false","--disk-cache=true"]#是数组形式,不加载浏览器图片,开启缓存
KEYWORD = "美食"
网友评论
submit = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR,"#J_TSearchForm > div.search-button > button")))
我是通过这样的选择器查找的这个按钮的
submit = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR,"#J_SearchForm button.submit")))
但是我的为什么查找不到?