目录:
Day05笔记
糗事百科-xpath
目标 : 用户昵称 段子内容 好笑数 评论数
步骤
-
xpath匹配
基准的xpath每个段子 : //div[contains(@id,“qiushi_tag_”)]
用户昵称 : ./div/a/h2
段子内容 : .//div[@class=“content”]/span
好笑数量 : .//i
评论数量 : .//i -
代码:
import requests from lxml import etree import pymongo class QiuShiSpider: def __init__(self): self.url = "https://www.qiushibaike.com/8hr/page/8/" self.headers = {"User-Agent":"Mozilla5.0"} self.conn = pymongo.MongoClient("localhost",27017) self.db = self.conn.BaiKe self.myset = self.db.baiketab def getPage(self): res = requests.get(self.url,headers=self.headers) res.encoding = "utf-8" html = res.text self.parsePage(html) def parsePage(self,html): parseHtml = etree.HTML(html) # 基准xpath,每个段子节点对象的列表 base_list = parseHtml.xpath('//div[contains(@id,"qiushi_tag_")]') # 遍历每个段子的节点对象 for children in base_list: # 用户昵称 username = children.xpath('./div/a/h2')[0].text # 段子内容 content = children.xpath('.//div[@class="content"]/span')[0].text # 好笑数量 laughNum = children.xpath('.//i')[0].text # 评论数量 pingNum = children.xpath('.//i')[1].text d = {"username": username.strip(), "content" : content.strip(), "laughNum": laughNum.strip(), "pingNum" : pingNum.strip() } self.myset.insert(d) if __name__ == "__main__": spider = QiuShiSpider() spider.getPage()
动态网站数据抓取 - Ajax
-
Ajax动态加载
-
特点 :动态加载(滚动鼠标滑轮时加载)
-
抓包工具 :查询参数在 WebForms -> QuerySting
-
案例 :豆瓣电影top100榜单(剧情)
-
豆瓣电影 -> 排行榜 -> 剧情:
import requests import json import csv url = "https://movie.douban.com/j/chart/top_list?" params = {"type":"11", "interval_id":"100:90", "action":"", "start":"0", "limit":"200"} headers = {"User-Agent":"Mozilla5.0"} res = requests.get(url,params=params,headers=headers) res.encoding = "utf-8" # 得到的json格式的数组[] html = res.text # 把json格式的数组转为python的列表 L = json.loads(html) for film in L: score = film["rating"][0] name = film["title"] with open("豆瓣100.csv","a",newline="") as f: writer = csv.writer(f) writer.writerow([name,score])
-
-
json模块
- 作用 : json格式类型 和 Python数据类型 相互转换
- 常用方法
-
json.loads() : json格式 --> Python数据类型
json python
对象 字典
数组 列表 -
json.dumps()
-
代码实例:
import json s1 = '[1,2,3,4]' L = json.loads(s1) print(type(L))
-
-
selenium + phantomjs 强大的网络爬虫
-
selenium
- 定义 : Web自动化测试工具,应用于Web自动化测试
- 特点
- 可运行在浏览器上,根据指令操作浏览器,让浏览器自动加载页面
- 只是工具,不支持浏览器功能,只能与第三方浏览器结合使用
- 安装
conda install selenium
pip install selenium
验证:
from selenium import webdriver
-
phantomjs
- 定义 : 无界面浏览器(无头浏览器)
- 特点
1.把网站加载到内存执行页面加载
2.运行高效 - 安装
- Windows
- 下载路径: 百度网盘下载
- 把安装包拷贝到 Python安装路径Scripts…
C:\Python36\Scripts
- 打开终端 : phantomjs
phantomjs>
- Windows
- Ubuntu
- 下载phantomjs安装包放到一个路径下
- 用户主目录 : vi .bashrc
export PHANTOM_JS=/home/.../phantomjs-..文件名
export PATH=$PHANTOM_JS/bin:$PATH
- source .bashrc
- 终端 : phantomjs
-
示例代码
-
for example:
# 导入selenium库中的webdriver from selenium import webdriver # 创建打开phantomjs的对象 driver = webdriver.PhantomJS() # 访问百度 driver.get("http://www.baidu.com/") # 获取网页截图 driver.save_screenshot("百度.png")
-
for example:
from selenium import webdriver # 操作键盘鼠标 from selenium.webdriver.common.keys import Keys import time driver = webdriver.PhantomJS() driver.get("http://www.baidu.com/") # 查找搜索框位置 driver.find_element_by_id("kw").send_keys(u"美女") #driver.save_screenshot("美女.png") driver.find_element_by_id("su").click() time.sleep(3) driver.save_screenshot("搜索.png")
-
-
常用方法
-
driver.get(url)
-
driver.page_source.find(“内容”)
-
作用 : 从html源码中搜索字符串
搜索成功 : 非-1
搜索不成功 : -1 -
for example:
from selenium import webdriver driver = webdriver.PhantomJS() driver.get("http://www.baidu.com/") r1 = driver.page_source.find("kw") # 能找到 17556 r2 = driver.page_source.find("aaaaaaa") # 失败-1 print(r1,r2)
-
-
driver.find_element_by_id(“属性值”).text
from selenium import webdriver driver = webdriver.PhantomJS() driver.get("http://www.baidu.com/") result = driver.find_element_by_id("setf").text print(result)
-
driver.find_element_by_name(“属性值”)
-
driver.find_element_by_class_name(“属性值”)
-
对象名.send_keys(“内容”)
-
对象名.click()
-
driver.quit()
-
-
案例1 :登陆豆瓣网站 :
from selenium import webdriver # 操作鼠标键盘 from selenium.webdriver.common.keys import Keys # 创建phantomjs浏览器对象 driver = webdriver.PhantomJS() driver.get("https://www.douban.com/") driver.save_screenshot("豆瓣首页.png") # 用户名 driver.find_element_by_name("form_email")\ .send_keys("[email protected]") # 密码 driver.find_element_by_name("form_password")\ .send_keys("zhanshen001") # 验证码 key = input("请输入验证码:") driver.find_element_by_id("captcha_field")\ .send_keys(key) # 登录豆瓣 driver.find_element_by_class_name("bn-submit")\ .click() driver.save_screenshot("登录成功.png") driver.quit()
-
案例 2 : 斗鱼直播抓取(JS分页加载,动态模拟点击)
- 抓取目标 : 主播 观众人数
- 主播 : span -> class=“dy-name ellipsis fl”
- 人数 : span -> class=“dy-num fr”
- 下一页
能点 : a -> class=“shark-pager-next”
不能点 :a -> class=“shark-pager-next shark-pager-disable shark-pager-disable-next” - 代码:
from selenium import webdriver from bs4 import BeautifulSoup as bs import time driver = webdriver.PhantomJS() driver.get("https://www.douyu.com/directory/all") while True: # 创建解析对象 soup = bs(driver.page_source,"lxml") # 直接调用方法去查找元素 # 存放所有主播的元素对象 names = soup.find_all('span',{"class":"dy-name ellipsis fl"}) numbers = soup.find_all('span',{"class":"dy-num fr"}) # name,number是一个对象,get_text() for name,number in zip(names,numbers): print("\t观众人数:",number.get_text().strip(), "\t主播名字:",name.get_text().strip()) if driver.page_source.find("shark-pager-disable-next") == -1: driver.find_element_by_class_name("shark-pager-next").click() time.sleep(4) else: break
-
-
BeautifulSoup
-
定义 :HTML或XML的解析器,依赖于lxml库
-
安装并导入
- 安装 :
pip install beautifulsoup4
conda install beautifulsoup4
- 安装模块出错处理:
- conda install selenium --> 报错
卸载 :conda uninstall selenium - 安装 :cmd 右键->管理员身份打开
python -m pip install selenium - 导入模块 :from bs4 import BeautifulSoup as bs
- conda install selenium --> 报错
- 安装 :
-
示例
from bs4 import BeautifulSoup html = "<div>九宵龙吟惊天变,风云际会浅水游</div>" # 创建解析对象 soup = BeautifulSoup(html,'lxml') # 查找div标签的文本 result = soup.div.string print(result)
-
BeautifulSoup支持解析库
- lxml HTML解析器 ‘lxml’ 速度快,文档容错能力强
- Python标准库 ‘html.parser’ 速度一般
- lxml XML解析器 ‘xml’ 速度快
-