安装:
Windows :安装selenium
python -m pip install selenium
Anaconda Prompt下执行 :
conda install selenium
Linux/Mac OS:
sudo pip3 install selenium
Ubuntu :安装Scrapy框架
#### 依赖库较多,以下为全部依赖库,有些已安装 ####
sudo apt-get install libssl-dev
sudo apt-get install libffi-dev
sudo apt-get install python3-dev
sudo apt-get install build-essential
sudo apt-get install libxml2
sudo apt-get install libxml2-dev
sudo apt-get install libxslt1-dev
sudo apt-get install zlib1g-dev
sudo pip3 install Scrapy
xpath工具(解析)
xpath
在XML文档中查找信息的语言,同样适用于HTML文档的检索
xpath辅助工具
Chrome插件 :XPath Helper
打开 :Ctrl + Shift + X
关闭 :Ctrl + Shift + X
Firefox插件 :XPath checker
XPath表达式编辑工具 :XML quire
xpath匹配规则
匹配演示
查找bookstore下所有节点:/bookstore
查找所有的book节点://book
查找所有book下的title节点中,lang属性为"en"的节点
//book/title[@lang="en"]
查找bookstore下的第2个book节点下的title节点:
/bookstore/book[2]/title/text()
选取节点
/ : 从根节点开始选取
// : 从整个文档中查找节点
//price 、 /bookstore/book//price
@ : 选取某个节点的属性
//title[@lang="en"]
@的使用
选取1个节点 : //title[@lang="en"]
选取N个节点 : //title[@lang]
选取节点的属性值 : //title/@lang
<a class=....,src="http://..."
匹配多路径
符号 : |
获取所有book节点下的 title节点和price节点
//book/title | //book/price
函数
contains() : 匹配一个属性值中包含某些字符串的节点
//title[contains(@lang,"e")]
text()
//title[contains(@lang,"e")]/text()
lxml库及xpath使用
lxml库 :HTML/XML解析库
安装
python -m pip install lxml
conda install lxml
使用流程
导模块
from lxml import etree
利用lxml库的etree模块创建解析对象
parseHtml = etree.HTML(html)
解析对象调用xpath工具定位节点信息
r_list = parseHtml.xpath('xpath表达式')
### 只要调用了xpath,结果一定是列表 ###
# 构造解析对象
parseHtml = etree.HTML(html)
# 利用解析对象调用xpath匹配
r1 = parseHtml.xpath('//a/@href')
print(r1)
# 获取 /
r2 = parseHtml.xpath('//a[@id="channel"]/@href')
print(r2)
# 获取非 /
r3 = parseHtml.xpath('//ul[@id="nav"]//a/@href')
print(r3)
# 获取所有 a 节点的文本内容
r4 = parseHtml.xpath('//a/text()')
print(r4)
# 获取 图片、军事 ...
r5 = parseHtml.xpath('//ul[@id="nav"]//a')
for i in r5:
print(i.text)
如何获取节点对象的内容
节点对象.text
抓取百度贴吧帖子里面所有的图片
目标 :抓取指定贴吧所有图片
思路
获取贴吧主页URL,下一页:找URL规律
获取1页中每个帖子的URL
对每个帖子URL发请求,获取帖子里图片URL
对图片URL发请求,以wb方式写入本地文件
步骤
获取贴吧主页URL
http://tieba.baidu.com/f? + 查询参数
找到页面中所有帖子的URL
src : 完整链接
href : 和主URL进行拼接
/p/5926064184
http://tieba.baidu.com/p/5926064184
xpath匹配链接:
写法1: //div[@class="col2_right j_threadlist_li_right"]/div/div/a/@href
写法2(推荐): //div[@class="t_con cleafix"]/div/div/div/a/@href
找每个帖子中图片URL
Xpath匹配:
//img[@class="BDE_Image"]/@src
'''02_百度贴吧图片抓取案例.py'''
import requests
from lxml import etree
import time
class BaiduImageSpider:
def __init__(self):
self.headers = {"User-Agent":"Mozilla/5.0"}
self.baseurl = "http://tieba.baidu.com"
self.pageurl = "http://tieba.baidu.com/f?"
# 获取所有帖子URL列表
def getPageUrl(self,params):
res = requests.get(self.pageurl,params=params,headers=self.headers)
res.encoding = "utf-8"
html = res.text
# 构建解析对象
parseHtml = etree.HTML(html)
# 帖子链接列表
t_list = parseHtml.xpath('//div[@class="t_con cleafix"]/div/div/div/a/@href')
# t_list : ['/p/233432','/p/2039820',..]
print(t_list)
for t_link in t_list:
# 拼接帖子完整链接
t_link = self.baseurl + t_link
self.getImageUrl(t_link)
# 获取帖子中图片URL列表
def getImageUrl(self,t_link):
res = requests.get(t_link,headers=self.headers)
res.encoding = "utf-8"
html = res.text
# 构造解析对象
parseHtml = etree.HTML(html)
img_list = parseHtml.xpath('//img[@class="BDE_Image"]/@src')
print(img_list)
for img_link in img_list:
self.writeImage(img_link)
# 保存到本地
def writeImage(self,img_link):
# 获取图片的bytes
res = requests.get(img_link,headers=self.headers)
res.encoding = "utf-8"
html = res.content
# filename
filename = img_link[-12:]
with open(filename,"wb") as f:
f.write(html)
time.sleep(0.5)
print("%s下载成功" % filename)
# 主函数
def workOn(self):
name = input("请输入贴吧名:")
begin = int(input("请输入起始页:"))
end = int(input("请输入终止页:"))
for n in range(begin,end+1):
pn = (n-1)*50
params = {
"kw":name,
"pn":str(pn)
}
self.getPageUrl(params)
if __name__ == "__main__":
spider = BaiduImageSpider()
spider.workOn()
糗事百科-xpath
目标 :用户昵称、段子内容、好笑数、评论数
找URL
https://www.qiushibaike.com/8hr/page/1/
xpath匹配
基准xpath://div[contains(@id,"qiushi_tag_")]
用户昵称: ./div/a/h2
段子内容: .//div[@class="content"]/span
好笑数量: .//i
评论数量: .//i
动态网站数据抓取
Ajax动态加载
特点 :滚动鼠标混轮时加载
抓包工具 :查询参数在 WebForms -> QueryString
'''03_糗事百科案例.py'''
import requests
from lxml import etree
import pymongo
class QiuShiSpider:
def __init__(self):
self.url = "https://www.qiushibaike.com/8hr/page/1/"
self.headers = {"User-Agent":"Mozilla/5.0"}
self.conn = pymongo.MongoClient("localhost",27017)
self.db = self.conn.Baikedb
self.myset = self.db.baikeset
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_")]')
# 遍历每个段子的节点对象(base)
for base in base_list:
# 用户昵称
username = base.xpath('./div/a/h2')
if len(username) == 0:
username = "匿名用户"
else:
username = username[0].text
# 段子内容
content = base.xpath('.//div[@class="content"]/span')[0].text
# 好笑数量
# [<element.好笑数量>,<eleme.评论>,<element...>]
laughNum = base.xpath('.//i')[0].text
# 评论数量
pingNum = base.xpath('.//i')[1].text
d = {
"username":username.strip(),
"content":content.strip(),
"laughNum":laughNum.strip(),
"pingNum":pingNum.strip()
}
self.myset.insert(d)
print("存入数据库成功")
if __name__ == "__main__":
spider = QiuShiSpider()
spider.getPage()