目录
4.ProxyBasicAuthHandler私密代理Handler处理器
存入csv文件
1.csv模块的使用流程
1.Python语句打开csv文件:
with open("测试.csv","a") as f:
pass
2.初始化写入对象
writer方法:writer = csv.writer(f)
3.写入数据
writerow()方法:writer.writerow([])
2.示例
import csv
with open("测试.csv","a",newline="") as f:
# 初始化写入对象
writer = csv.writer(f)
# 写入数据 writer.writerow([])
writer.writerow(["id","name","age"])
writer.writerow(["1","Lucy","20"])
writer.writerow(["2","Tom","25"])
2.Xpath 工具(解析html)
1.Xpath
在XML文档中查找信息的语言,同样适用于HTML文档的检索
2.Xpath辅助工具
1.Chrome插件:XPath Helper
打开/关闭:Ctrl+Shift+大写X
2.FireFox插件:Xpath checker
3.XPath表达式编辑工具:XML Quire
3.XPath匹配规则
1.匹配演示
1.查找bookstore下面的所有节点: /bookstore
2.查找所有book节点: //book
3.查找所有book节点下title节点中,lang属性为"en"的节点://book/title[@lang="en"]
2.选取节点
/ : 从根节点开始选取 /bookstore
//: 从整个文档中查找某个节点 //price
@ : 选取某个节点的属性 //title[@lang="en"]
3.@使用
1.选取1个节点://title[@lang="en"]
2.选取n个节点://title[@lang]
3.选取某个节点的属性值://title/@lang
4.匹配多路径
1.符号: |
2.示例
获取所有book节点下的title节点和price节点
//book/title | //book/price
5.函数
contatins() : 匹配1个属性值中包含某些字符串的节点
//title[contains(@lang,"e")]
3.解析HTML源码
1.lxml库:HTML/XML解析库
1.安装
conda install lxml
pip install lxml
uninsall
remove
autoremove
2.使用流程
1.利用lxml库的etree模块构建解析对象
2.解析对象调用xpath工具定位节点信息
2.使用
1.导入模块 from lxml import etree
2.创建解析对象:parseHtml = etree.HTML(html)
3.调用xpath进行解析:
r_list = parseHtml.xpath('//title[@lang="en"]')
# 只要调用了xpath,则结果一定是列表
3.示例+练习
4.案例:抓取百度贴吧帖子里面的图片
1.目标:抓贴吧中帖子图片
2.思路
1.获取贴吧主页URL:美女吧 下一页:URL规律
2.获取美女吧中每个帖子的URL
3.对每个帖子发请求,获取帖子里所有图片的URL
4.对图片URL发请求,以wb的方式写入本地文件
3.步骤
1.获取贴吧的URL
http://tieba.baidu.com/f? + 一堆查询参数
pn = (page-1)*50
2.获取每个帖子的URL
http://tieba.baidu.com + /p/5866881218
//div[@class="threadlist_title pull_left j_th_tit "]/a/@href
3.打开每个帖子
http://imgsrc.baidu.com/forum/w%3D580/sign=8bac1b1a10950a7b75354ecc3ad0625c/3c0bddc451da81cbfe7fc3e15f66d016082431e2.jpg
xpath匹配 //img[@class="BDE_Image"]/@src
4.保存到本地
4.ProxyBasicAuthHandler私密代理Handler处理器
1.密码管理器使用流程
1.创建密码管理器对象
pwd = urllib.request.HTTPPasswordMgrWithDefaultRealm()
2.添加私密代理用户名,密码,IP地址,端口信息
pwd.add_password(None,"IP:端口","用户名","密码")
1.urllib.request.ProxyBasicAuthHandler(密码管理器对象)
import urllib.request
server = "114.67.228.126:16819"
user = "309435365"
password = "szayclhp"
url = "http://www.baidu.com/"
tarenaUrl = "http://code.tarena.com.cn/"
# 密码管理器对象操作
pwd = urllib.request.HTTPPasswordMgrWithDefaultRealm()
pwd.add_password(None,server,user,password)
#pwd.add_password(None,tarenaUrl,"tarenacode","code_2013")
# 创建处理器对象
proxy_handler = urllib.request.ProxyBasicAuthHandler(pwd)
opener = urllib.request.build_opener(proxy_handler)
# 发请求
req = urllib.request.Request(url)
res = opener.open(req)
html = res.read().decode("utf-8")
print(html)
xpath示例
from lxml import etree
html = """<div class="wrapper">
<i class="iconfont icon-back" id="back"></i>
<a href="/" id="channel">新浪社会</a>
<ul id="nav">
<li><a href="http://domestic.firefox.sina.com/" title="国内">国内</a></li>
<li><a href="http://world.firefox.sina.com/" title="国际">国际</a></li>
<li><a href="http://mil.firefox.sina.com/" title="军事">军事</a></li>
<li><a href="http://photo.firefox.sina.com/" title="图片">图片</a></li>
<li><a href="http://society.firefox.sina.com/" title="社会">社会</a></li>
<li><a href="http://ent.firefox.sina.com/" title="娱乐">娱乐</a></li>
<li><a href="http://tech.firefox.sina.com/" title="科技">科技</a></li>
<li><a href="http://sports.firefox.sina.com/" title="体育">体育</a></li>
<li><a href="http://finance.firefox.sina.com/" title="财经">财经</a></li>
<li><a href="http://auto.firefox.sina.com/" title="汽车">汽车</a></li>
</ul>
<i class="iconfont icon-liebiao" id="menu"></i>
</div>"""
# 1.构建解析对象
parseHtml = etree.HTML(html)
# 2.解析对象调用 xpath 工具
# 获取所有a标签的 href属性值
r_list = parseHtml.xpath('//a/@href')
#for i in r_list:
# print(i)
# 获取 /
r_list = parseHtml.xpath('//a[@id="channel"]/@href')
#print(r_list)
# 获取 非 /
#r_list = parseHtml.xpath('//ul[@id="nav"]/li/a/@href')
r_list = parseHtml.xpath('//ul[@id="nav"]//a/@href')
#print(r_list)
# 获取所有<a>节点的文本内容
r_list = parseHtml.xpath('//a')
# 得到的是元素对象,需要用 对象名.text 获取内容
#for i in r_list:
# print(i.text)
# 获取 新浪社会
r_list = parseHtml.xpath('//a[@id="channel"]')
#for i in r_list:
# print(i.text)
# 获取非 新浪社会 的节点文本
r_list = parseHtml.xpath('//ul[@id="nav"]//a')
for i in r_list:
print(i.text)
百度贴吧图片获取
import requests
from lxml import etree
class BaiduImageSpider:
def __init__(self):
self.headers = {"User-Agent":"Mozilla5.0/"}
self.baseurl = "http://tieba.baidu.com"
self.pageurl = "http://tieba.baidu.com/f?"
# 获取每个帖子的url
def getPageUrl(self,params):
# 得到贴吧第1页html源码
res = requests.get(self.pageurl,params=params,headers=self.headers)
res.encoding = "utf-8"
html = res.text
# 从html源码获取帖子链接 '/p/2323432'
parseHtml = etree.HTML(html)
t_list = parseHtml.xpath('//div[@class="t_con cleafix"]/div/div/div/a/@href')
# ['/p/2342443','/p/08098034']
for t in t_list:
t_url = self.baseurl + t
self.getImageUrl(t_url)
# 获取帖子中所有图片的URL
def getImageUrl(self,t_url):
# 获取帖子的html源码,为了从中筛选图片URL
res = requests.get(t_url,headers=self.headers)
res.encoding = "utf-8"
html = res.text
# 得到图片URL
parseHtml = etree.HTML(html)
i_list = parseHtml.xpath('//img[@class="BDE_Image"]/@src')
#['http://...jpg','http://...png',...]
for i in i_list:
self.writeImage(i)
# 保存到本地
def writeImage(self,i):
# 获取图片的html源码 bytes
res = requests.get(i,headers=self.headers)
res.encoding = "utf-8"
html = res.content
# 保存到本地
filename = i[-10:]
with open(filename,"wb") as f:
print("%s正在下载" % filename)
f.write(html)
print("%s下载成功" % filename)
# 主函数
def workOn(self):
name = input("请输入贴吧名字:")
begin = int(input("请输入起始页:"))
end = int(input("请输入终止页:"))
for page in range(begin,end+1):
pn = (page-1)*50
params = {
"kw":name,
"pn":str(pn)
}
self.getPageUrl(params)
if __name__ == "__main__":
spider = BaiduImageSpider()
spider.workOn()