爬虫第三篇
requests模块用法 :http://2.python-requests.org/zh_CN/latest/user/quickstart.html
get请求
import requests
# 1.发get请求
res = requests.get(url,params,headers,proxies,auth,verify,timeout)
# 2.响应 编码格式
res.encoding = "utf-8"
# 3. 获取html
html = res.text
requests.get(url,params,headers,proxies,auth,verify)
参数:params : 查询参数,自动拼接在URL后
headers : 请求头文件,一般需要设置User-Agent
proxies : 代理
auth : Web 客户端验证
verify : SSL证书认证
proxies:
1.获取IP地址的网站:快代理和全网代理
2.普通代理
格式:proxies={"协议":"协议://IP:端口号"}
e.g. proxies={"http":"http://37.192.32.213:36344"}
3.私密代理
格式:proxies={"http":"http://用户名:密码@IP地址:端口号"}
auth :auth = ("用户名","密码")
verify:
1.verify = True(默认):进行CA证书认证
2.verify = False :不进行认证
# 响应对象res属性
res.encoding : 相应编码
res.text : 以字符串形式获取响应内容
res.content : 以bytes的形式获取响应内容
res.status_code : HTTP 响应对象
res.url : 返回实际数据的URL地址
#非结构化数据保存(图片,视频)
html = res.content
with open("***.jpg","wb") as f:
f.write(html)
post请求
1. requests.post(url,data=data,headers,proxies,auth,verify,timeout)
2. data:字典,Form表单数据,不用编码,不用转码
Xpath解析工具
1. 在XML文档中查找信息的语言,同样适用于HTML文档的检索
2. xpath辅助工具
1. Chrome插件 :XPath Helper
打开/关闭 :Ctrl + shift + x
2. Firefox插件:XPath Checker
3. XPath编辑工具:XML quire
XPath常用规则
表达式 | 描述 |
---|---|
nodename | 选择这个节点名的所有子节点 |
/ | 从当前节点选择直接子节点 |
// | 从当前节点选取子孙节点 |
. | 选择当前节点 |
… | 选取当前节点的父节点 |
@ | 选取属性,如: //div[@lang=‘eng’] |
| | 匹配多路径,如:xpath表达式1 | xpath表达式2 |
contains() | 匹配属性值中包含某些字符串的所有节点,如: //div[contains(@class,“njjzw”)] |
text() | 获取文本 |
lxml事例说明
article 选取所有article元素的所有子节点
/article 选取根元素article
article/a 选取所有属于article的子元素的a元素
//div/ 选取所有div子元素(不论出现在文档任何地方)
article//div 选取所有属于article元素的后代的div元素,不管它出现在article下的任何位置
//@class 选取所有名为class的属性
/article/div[1] 选取属于article子元素的第一个div元素
/article/div[last()] 选取属于article子元素的最后一个div元素
/article/div[last()-1] 选取属于article子元素的倒数第二个div元素
//div[@class] 选取所有拥有class属性的div元素
//div[@class='article'] 选取所有class属性为article的div元素
//div[@class='article']/text() 选取所有class属性为article的div元素下的text值
/div/* 选取属于div元素的所有子节点
//* 选取所有元素
//div[@*] 选取所有带属性的div元素
//div/a | //div/p 选取所有div元素下的a和p元素
//span|//ul 选取文档中的span和ul元素
article/div/p | //span 选取所有属于article元素的div元素的p元素以及文档中所有的span元素
常用的函数:
一、精确定位
1)contains(str1,str2) 用来判断str1是否包含str2
例1://*[contains(@class,'c-summaryc-row ')] 选择@class值中包含c-summary c-row的节点
例2://div[contains(.//text(),'价格')] 选择text()中包含价格的div节点
2)position() 选择当前的第几个节点
例1://*[@class='result'][position()=1] 选择@class='result'的第一个节点
例2://*[@class='result'][position()<=2] 选择@class='result'的前两个节点
3)last() 选择当前的倒数第几个节点
例1://*[@class='result'][last()] 选择@class='result'的最后一个节点
例2://*[@class='result'][last()-1] 选择@class='result'的倒数第二个节点
4)following-sibling 选取当前节点之后的所有同级节点
例1://div[@class='result']/following-sibling::div 选择@class='result'的div节点后所有同级div节点 找到多个节点时可通过position确定第几个如://div[@class='result']/following-sibling::div[position()=1]
5)preceding-sibling 选取当前节点之前的所有同级节点
使用方法同following-sibling
二、拼接信息
1)concat() 函数用于串连多个字符串
例子:concat('http://baidu.com',.//*[@class='c-more_link']/@href)
lxml库及xpath使用
1. 安装
管理员Prompt : conda install lxml
2. 使用流程
1. 导模块
from lxml import etree
2. 创建解析对象
parseHtml = etree.HTML(html)
3. 调用xpath
rList=parseHtml.xpath('xpath表达式')
** 只要调用了xpath,结果一定是列表
import requests
from lxml import etree
from multiprocessing import Queue, Process
class BaiduImageSpider(object):
u"""爬取百度贴吧的图片"""
def __init__(self):
self.base_url = "https://tieba.baidu.com/f?"
self.headers = {"User-Agent":"Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0)"}
self.urls = set()
def get_request_url(self, url, params):
res = requests.get(url, params=params, headers=self.headers)
res.encoding = 'utf-8'
html = res.text
# 提取url
parse_html = etree.HTML(html)
url_list = parse_html.xpath("//div[@class='t_con cleafix']/div/div/div/a/@href")
for url in url_list:
self.urls.add(url)
self.get_image_url(self.urls)
def get_image_url(self, urls):
for url in urls:
url = '%s%s' % ('https://tieba.baidu.com', url)
res = requests.get(url, headers=self.headers)
res.encoding = 'utf-8'
html = res.text
# 提取图片的链接
parse_html = etree.HTML(html)
image_urls= parse_html.xpath('//div[@class="d_post_content j_d_post_content clearfix"]/img[@class="BDE_Image"]/@src | //div[@class="video_src_wrapper"]/embed/@data-video')
self.get_image(image_urls)
def get_image(self, image_urls):
for url in image_urls:
res = requests.get(url, headers=self.headers)
res.encoding = 'utf-8'
html = res.content
# 保存图片
filename = url[-20:]
with open('./beauty/%s' % filename, 'ab') as f:
f.write(html)
print('%s下载成功!' % filename)
def start_spider(self):
content = '美女吧'
start = 1
end = 50
for i in range(start, end):
params = {
'kw': content,
'pn': 50 * (i-1)
}
self.get_request_url(self.base_url, params)
if __name__ == "__main__":
spider = BaiduImageSpider()
pList = []
for i in range(10):
p = Process(target=spider.start_spider)
pList.append(p)
p.start()
for p in pList:
p.join()
import requests
from lxml import etree
import pymongo
class QiushiSpider:
def __init__(self):
self.url = "https://www.qiushibaike.com/text/"
self.headers = {"User-Agent":"Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0)"}
# 连接对象
self.conn = pymongo.MongoClient("192.168.56.129",27017)
# 库对象
self.db = self.conn["Qiushidb"]
# 集合对象
self.myset = self.db["zhuanye"]
# 获取页面
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,每个段子对象
# ['<element...>','<element...>','']
baseList = parseHtml.xpath('//div[contains(@id,"qiushi_tag_")]')
# for循环遍历每个段子对象,1个1个提取
for base in baseList:
# base : <element at ....>
# 用户昵称
username = base.xpath('./div/a/h2')
if username:
username = username[0].text.strip()
else:
username = "匿名用户"
# 段子内容
content = base.xpath('./a/div[@class="content"]/span/text()')
content = "".join(content).strip()
# 好笑数量
laughNum = base.xpath('.//i[@class="number"]')[0].text
# 评论数量
pingNum = base.xpath('.//i[@class="number"]')[1].text
# 定义字典存mongo
d = {
"username":username,
"content" :content.strip(),
"laughNum":laughNum,
"pingNum" :pingNum,
}
self.myset.insert_one(d)
# 主函数
def workOn(self):
print("正在爬取中......")
self.getPage()
print("爬取结束,存入Qiushidb库")
if __name__ == "__main__":
spider = QiushiSpider()
spider.workOn()