今天刚接触了selenium,selenium是什么??网上搜了一下,大概是这么理解的, selenium叫做自动化测试,在爬虫里边的作用个人理解是:如果用动态加载,可以把动态加载后的页面返回给我们(相当于点击检查后看到的页面、response.page_source获取网页渲染后的源代码)而requests只能返回静态的页面,selenium可以模拟浏览器,可见的去操作,可以做很多,比如模拟下拉操作,模拟登陆、模拟点击按钮,模拟提交表单等。
selenium支持的浏览器包括IE(7, 8, 9, 10, 11),Mozilla Firefox,Safari,Google Chrome,Opera。
selenium用于爬虫,主要是用来解决javascript渲染的问题
但是在使用之前需要安装两个东西
1、selenium
安装的方法:进入cmd窗口输入pip install selenium
2、还需要下载浏览器对应的驱动器(driver),我用的是chrom,所以下载了chromdriver2.4最新的。浏览器和驱动器的版本要对应起来,不知道浏览器版本该用哪个驱动器的去搜一下,很好找。driver的下载地址是(需要翻墙,反正我是被墙了的):http://chromedriver.storage.googleapis.com/index.html
下载下来之后就把他放到Anaconda的安装路径下就行了。
一个简单的例子:
from selenium import webdriver
import time
browser = webdriver.Chrome()
browser.get('https://www.baidu.com')
input = browser.find_element_by_id('kw')
input.send_keys('python selenium')
time.sleep(1)
butt = browser.find_element_by_id('su')
butt.click()
执行这段代码就可以实现在百度自动输入python selenium并点击操作得到如下结果
模拟登录也是类似这样的做法,如下:
from selenium import webdriver
import time
browser = webdriver.Chrome()
browser.get('http://211.64.28.123/jwglxt/xtgl/login_slogin.html?language=zh_CN&_t=1534213167679')
input1 = browser.find_element_by_id('yhm')
input2 = browser.find_element_by_id('mm')
input1.send_keys('学号')
time.sleep(1)
input2.send_keys('密码')
time.sleep(1)
button = browser.find_element_by_id('dl')
button.click()
print(input1)
print(browser.page_source)
执行这段代码就能实现自动登录学校教务系统,并返回登录后的页面源码
一个小的实用例子,利用了selenium爬取了淘宝的零食页面,在进入详情页以后,价格是我们直接从源码里边找不到的,但用selenium来爬取就会很容易得到js渲染后的页面得到我们想要的内容。url:https://s.taobao.com/search?q=零食 从这里进入到每个零食的详情页面,那就涉及到了一个问题,进入每个商品的url是什么?
通过观察发现每个商品的url = 'https://detail.tmall.com/item.htm?id='+id变化的就是id部分,判断是商品的id,那就用这种方式构造详情页的url,但是又有一个问题,id去哪找???通过一次次尝试,通过selenium获得页面源码,在里边搜索,发现id在一个a标签中的id=J_Itemlist_TLink_535330755707最后,为什么不选则后边的,因为它取出来不唯一 理论是这样的,但是我怎么取出这个数字呢,这么一大串,这样的话,想了想beautifulsoup的select方法?xpath?这些感觉都太麻烦,直接用正则就可以简单的取出id了正则构造这这样的
ids = re.findall(r'id="J_Itemlist_TLink_(.*?)"', response.page_source)#正则匹配
这样就能取出id了,然后就可以构造出上边所说的详情页url了,我是构造一个url就解析一下,并写入csv,为什么这样?因为怕麻烦,也可以先构造好一页中所有的商品的详情页的url然后再去一个个解析,这里还有一个问题是,selenium在爬取的时候由于模拟浏览器,每次都会打开浏览器,所以比较慢,就爬一个写入一个,多了等起来累,最关键的是访问次数太多,会被重定向到天猫登录页面,我成功把我自己和同桌的热点搞来不能直接访问详情页面,被重定向了。所以,建议爬一下,适当停顿一点时间。完整代码:
from selenium import webdriver
import re
from bs4 import BeautifulSoup
import time
import csv
#获得url页面内容
def getHtml(url):
try:
browser = webdriver.Chrome()
browser.get(url) # 返回的是看到的源码
return browser
except:
print('爬取出错')
return ''
#获得商品的id
def getId(response):
try:
ids = re.findall(r'id="J_Itemlist_TLink_(.*?)"', response.page_source)#正则匹配
return ids
except:
print('获得id失败')
return ''
#解析详情页面
def detail_parse(response):
try:
info = []
soup = BeautifulSoup(response.page_source,'html.parser')
name = soup.select('.tb-detail-hd h1')[0].text #获得商品名字
price = soup.select('.tm-promo-price .tm-price')[0].text #获得商品价格
addr = soup.select('.tb-deliveryAdd')[0].text #产地
shop_name = soup.select('.slogo-shopname strong')[0].text #店铺名字
month_sale = soup.select('.tm-ind-item.tm-ind-sellCount .tm-count')[0].text #月销售量
pingjia = soup.select('.tm-ind-item.tm-ind-reviewCount.canClick.tm-line3 .tm-count')[0].text #评价数
renqi = soup.select('#J_CollectCount')[0].text.replace('(','').replace('人气)','')#人气
info.append(name.strip())
info.append(shop_name)
info.append(addr)
info.append(price)
info.append(month_sale)
info.append(pingjia)
info.append(renqi)
return info
except:
print('解析失败')
return ''
#写CSV的函数
def CSVwrite(lstt):
with open("淘宝零食数据.csv", "w", newline="") as datacsv:
# dialect为打开csv文件的方式,默认是excel,delimiter="\t"参数指写入的时候的分隔符
csvwriter = csv.writer(datacsv, dialect=("excel"))
csvwriter.writerow(["商品名称", "店铺", "产地", "价格", "月销量", "累计评价", "人气"])
# csv文件插入一行数据,把下面列表中的每一项放入一个单元格(可以用循环插入多行)
for lst in lstt:
try:
csvwriter.writerow(lst)
except:
print('失败一个')
continue
print('写入完成')
def main():
info_list = []
url = 'https://s.taobao.com/search?q=零食'
res = getHtml(url)
ids = getId(res)
for id in ids:
url1 = 'https://detail.tmall.com/item.htm?id='+id #构造商品详情url
resp = getHtml(url1) #请求url页面
lst = detail_parse(resp) #调用解析函数
info_list.append(lst)
CSVwrite(info_list) #写入csv
time.sleep(1) #休眠1秒
# CSVwrite(info_list) # 在for循环完成才写入csv的话太慢还可能遇到其他错误,所以放到了for循环里边
main()
我用的是beautifulsoup解析的,也可以用正则,正则相对来说会简单一些,但我觉得beautifulsoup更直观、好理解。最后的结果,存了csv
由于网速原因,所以只爬了几个商品。这里只实现了爬取一页的情况,想要爬取多页的话,通过以前的经验,知道淘宝的下一页的url可以构造成这样https://s.taobao.com/search?q=零食&s=str(i*44)i=0、1、2、3、4、……,用for循环即可实现,当然要在最大页范围内。
网友评论