python学习:python爬虫
Python爬虫
在网站上运行自动化脚本,获取相关信息。爬虫分为定向和非定向,定向指定爬取网站类型,非定向脚本自动爬取网站类型。
爬虫过程
1、请求网站地址,拿到网站的html代码;
2、筛选出对应链接地址,信息;
使用data=requests.get(网址),获取网站。data.text可以拿到网站html代码。
使用beautisoup模块,将html代码文本转换为一个对象。
安装对应模块:
安装requests模块,pip3 install requests
安装beautifulsoup4,pip 3 install beautifulsoup4
示例1:
创建pachong.py
#爬虫
#爬取汽车资讯信息
import requests
from bs4 import BeautifulSoup
response = requests.get("https://www.autohome.com.cn/all/")
#将编码格式指定为网页编码格式
response.encoding=response.apparent_encoding
print(response.text)
#使用beautifulsoup将文本转换为对象
#features:转换引擎,默认"html.parser",也可使用""
soup = BeautifulSoup(response.text,features="html.parser")
print(soup)
#查找到id为"auto-channel-lazyload-article"的节点div
target = soup.find(id="auto-channel-lazyload-article")
#查找一个li标签
li_obj = target.find("li")
#查找所有li标签
li_list = target.find_all("li")
#循环list
for item in li_list:
#查找到每个li中a标签
a_obj = item.find("a")
if a_obj:
#获取a标签属性字典
print(a_obj.attrs)
print(a_obj.attrs["href"])
#查找h3标签
h3_obj = item.find("h3")
if h3_obj:
#拿到标签的文本
print(h3_obj.text)
#查找img标签
img_obj = item.find("img")
if img_obj:
img_url = "http:" + img_obj.attrs["src"]
img_data = requests.get(img_url)
#生成文件名
import uuid
img_name = str(uuid.uuid4()) + ".jpg"
with open(img_name,"wb") as f:
#使用content返回二进制数据,text是字符串文本
f.write(img_data.content)
模块使用
requests模块
data = requests.get(url):获取访问网址,get请求
data=requests.post(url,cookie={},data={}):post请求,data发送数据,cookie发送的cookies;
data.text:网址的html文本;
data.content :网址的二进制文本;
data.Encoding:编码,指定编码为data.apparent_encoding,原网页编码;
data.cookies.get_dict():获取cookies字典;
beautifulsoup4模块
导入from bs4 import BeautifulSoup;
使用soup = BeautifulSoup(data.text,features=””),将requests返回html文本转换为对象,features指定转换引擎;
soup.find(“”),查找对应的tag标签;
soup.find_all(“”),查找所有对应tag标签;
示例2:
创建pachong1.py
#爬虫
#自动登陆github
import requests
from bs4 import BeautifulSoup
#模拟登陆github过程
#get请求访问https://github.com/login
data_get = requests.get("https://github.com/login")
#查看cookies字典
dict_cookies = data_get.cookies.get_dict()
# print(dict_cookies)
# print(data_get.text)
#转换成对象
soup = BeautifulSoup(data_get.text,features="html.parser")
#获取登陆表单信息
form_dict = {}
target_form = soup.find("form")
input_list = target_form.find_all("input")
for item in input_list:
if item.attrs.get("value",None):
form_dict[item.attrs["name"]] = item.attrs["value"]
#填写登陆信息
#登陆表单信息
form_dict["login"] = "账号"
form_dict["password"] = "密码"
print(form_dict)
#提交登陆请求
data_post = requests.post(
url="https://github.com/session",
data=form_dict,
cookies = dict_cookies
)
#获取cookies字典
print(data_post.text)
requests模块详解
默认提交方式的方法:
requests.get();
requests.post();
requests.put();
requests.delete();
request()方法
requests.request():
参数:
1、method:提交方式;
2、url:提交地址;
3、params:URL上传递的参数,就是?参数=值形式,params接收一个字典值;
4、data:传递数据,post请求body的内容,data接收一个字典,字符串(“k1=v1&k2=v2”),文件对象;
5、json:post请求体传递数据,将数据整体使用json格式化;
json方式提交
请求头:content-type : application/json
请求体:“{k1:v1,k2:v2}”
data方式提交
请求头:content-type : application/url-form-encoding
请求体:{k1:v1,k2:v2}
6、cookies : Cookies,放在请求头中
7、files:文件,上传文件,files接收格式可以是字典;
字典值是一个元组,元组第一个值是上传到服务器自定义文件名,第二个值是文件对象open(“a.txt”,”wb”)
{
“k1”:(“test.txt”,open(“a.txt”,”wb”),)
}
8、auth:将用户密码账号进行简单加密;
9、timeout:设置超时,接收参数float或者元组;
10、allow_redirects:是否允许重定向,布尔值;
11、proxies:代理,接收字典
{
“http”:”地址”
}
12、stream:True or False,流方式下载文件,不会全部取到,而是像水流一样读取;
13、verify:True or False,False忽略证书是否存在;
14、cert:证书,https请求时,如果没有证书,访问失败;
requests.Session()方法
保存客户端历史访问信息
session = requests.Session()
使用session.get(),session.post()可以省略掉传递cookies参数的步骤,因为使用session提交请求时,自动将之前请求的cookies,请求头信息传递到下次请求。
BeautifulSoup模块详解
soup = BeautifulSoup(requests返回html, features=””)
BeautifulSoup类实例化参数:
参数1:传入requests获取到的requests.get().text()
参数2:features解析引擎,python默认的是html.parser,速度适中,容错率强;lxml:速度快,容错率高,需要安装c语言库;xml:速度快,支持XML解析,需要安装c语言库;
如果要使用lxml,使用安装pip install lxml
查找返回对应标签对象:
查找指定标签
soup.find(“标签名”)
find参数,recursive = True or False是否递归查找
find参数,attrs = {“class”:”c1”},传入字典
find参数,text = “”
find参数,name=””
find参数,class_ = “”
一般直接使用attrs作为条件,将其他属性条件放在attrs字典中。
查找所有指定标签
soup.find_all(“标签名”)
find的参数对find_all()都适用
属性也可以传列表
soup.find_all(name =[“div”,”a”])
查找指定id,select()可以根据CSS选择器查找
soup.select(“#id”)
soup.select(“.cls”)
soup.select(“body a”)
soup.select(“body > a”)
soup.select(“span,a“)
使用正则表达式查找
import re
rep = re.compile(“div.”)
soup.find(name =rep)
查找当前标签在父标签index
body_tag = soup.find(“body”)
查找body中的一个div的index
body_tag.index(soup.find(“div”))
标签对象<class 'bs4.element.Tag'>
属性:
tag.name:标签名<a>、<div>等;
tag.attrs:属性字典,通过属性字典键值实现赋值修改等操作;
tag.string:获取标签内容,也可以tag.string=””修改标签内容
关联标签属性
当前标签后标签
tag.next
tag.next_element
tag.next_elements
tag.next_sibling
tag.next_siblings
当前标签前标签
tag.previous
tag.previous_element
tag.previous_elements
tag.previous_sibling
tag.previous_siblings
当前标签父标签
tag.parent
tag.parents
tag.children:获取所有子标签,包括换行;
方法:
tag.extract():删除标签,及子标签包括自己,返回删除标签;
tag.decompose():删除标签,及子标签包括自己;
tag.clear():清空所有子标签,保留自身标签名;
tag.decode():将当前标签转换为字符串,decode_contents()只将标签内子标签转换为字符串,不包括当前标签;
tag.encode():将当前标签转换为字节;
增加标签内容
tag.append():当前标签追加内容,如果加入内容是已有标签,会将原有内容移动到当前标签最后;
tag.insert(index,tag):当前标签插入内容,index:指定位置;
tag.insert_after():当前标签后插入内容;
tag.insert_before():当前标签前插入内容;
tag.replace_with():当前标签替换为指定内容;
查找关联标签
tag.find_next();
tag.find_next_sibling();
tag.find_next_siblings();
tag.find_previous();
tag.find_previous_sibling();
tag.find_previous_siblings();
tag.find_parent();
tag.find_parents();
包裹标签
tag.wrap():当前标签包裹指定标签
tag.unwrap():当前标签去掉标签,只保留内容
实例:
#爬虫
#BeautifulSoup使用详解
from bs4 import BeautifulSoup
#读取html文件
with open("test.html") as f:
data = f.read()
#获取BeautifulSoup对象
soup = BeautifulSoup(data,features="html.parser")
#soup的查找标签
#find方法()
#查找指定tag名,recursive=True是否递归查找,
tag = soup.find(name = "p",recursive=True)
#查找指定tag内容
tag = soup.find(text="Apache Cordova")
#查找指定id
tag = soup.find(id = "deviceready")
#查找指定class
tag = soup.find(class_ = "event listening")
#查找指定属性值的tag,attrs传入字典,多个属性值条件筛选
tag = soup.find(attrs={"class":"event listening","about":"test"})
#find_all()方法
tags = soup.find_all(name="p",recursive=True)
#条件可以传入列表
tags = soup.find_all(name=["p","span"])
#select()方法,通过CSS选择器查找
#id选择器,返回一个Tag对象
tags = soup.select("#deviceready")
#类选择器查找,返回一个列表
tags = soup.select(".app")
#组合选择器
tags = soup.select("div .event")
#使用正则表达式匹配
import re
rep = re.compile("h(\d)")
#查找span的tag名的标签
tags = soup.find(name = rep)
#标签对象Tag的属性方法
body_tag = soup.find("body")
#Tag属性
# #标签名
# print(body_tag.name)
# #标签属性
# print(body_tag.attrs)
# #标签内容,如果 标签包含标签,内容为None,
# print(body_tag.string)
# print(soup.find("span").string)
# #查找结点下一个结点,
# print(soup.find("h1").next)
# #查找父标签Tag,返回Tag对象
# print(soup.find("h1").parent)
#Tag方法
#将Tag内部标签全部删除
# body_tag.clear()
#将Tag内部标签删除,包括自己,返回删除标签
#rest = body_tag.extract()
#删除Tag标签包括自己
#body_tag.decompose()
#将本标签对象转换为字符串,返回
# rest = body_tag.decode()
#将标签对象转换为字节
# rest = body_tag.encode()
#加入标签
from bs4 import Tag
#创建Tag对象
tag_a = Tag(name="a",attrs={"id":"append_a","class":"ctest","href":"#"})
tag_a.string = "hello world"
#将标签加入body中,追加
# body_tag.append(tag_a)
#将标签插入body指定位置
# body_tag.insert(0,tag_a)
#在标签前后插入
# h1_tag = soup.find("h1")
#在当前标签后插入
# h1_tag.insert_after(tag_a)
#在当前标签前插入
# h1_tag.insert_before(tag_a)
爬虫性能优化
单个request请求,爬取网站;
多个request请求并发操作,爬取网站;
多线程实现并发请求
#爬虫
#性能优化,多线程实现并发请求
from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor
import requests
#计算时,需要使用CPU,每个进程有GIL锁,进程中只有一个线程可以使用cpu,
#所有计算密集型,开多线程没意义
#当遇到IO密集型,使用多线程
#计算密集型,使用多进程
#创建线程池
pool = ThreadPoolExecutor(5)
#创建进程池
# ppool = ProcessPoolExecutor
#请求列表
url_list=[
"https://www.baidu.com",
"https://www.bootcss.com/",
"https://www.runoob.com/",
"https://www.cnblogs.com/"
]
#请求页面
def task(url):
response = requests.get(url)
print(url,response)
#请求成功,回掉函数
def result_back(future,*args,**kwargs):
#future类对象,result()获取到response
# response = future.result()
#获取不到response,result返回None
print(type(future))
print(future.result())
if __name__ == "__main__":
#请求列表使用线程池
for item in url_list:
#开始线程
v = pool.submit(task,item)
#设置回调函数
v.add_done_callback(result_back)
pool.shutdown(wait=True)
使用异步I/O,单线程多任务并发请求
# #使用gevent+requests
# from gevent import monkey
# monkey.patch_all()
# import gevent
# import requests
# #执行请求方法
# def func_async(method,url,req_kwargs):
# print(url)
# response = requests.request(method=method,url=url,**req_kwargs)
# print(response.url)
# print(response.content.decode(encoding="utf-8"))
# #创建协程池(最大协程数量)
# from gevent.pool import Pool
# pool = Pool(5)
# gevent.joinall([
# gevent.spawn(func_async,method="get",url="https://www.baidu.com/",req_kwargs={}),
# gevent.spawn(func_async,method="get",url="https://www.cnblogs.com/",req_kwargs={}),
# gevent.spawn(func_async,method="get",url="https://www.runoob.com/",req_kwargs={}),
# ])
# #使用grequest模块
# import grequests
# #请求列表
# request_lists=[
# grequests.get("https://www.baidu.com"),
# grequests.get("https://www.cnblogs.com/"),
# ]
# #执行请求列表
# reponse_lists = grequests.map(request_lists)
# print(reponse_lists)
本文来自博客园,作者:渔歌晚唱,转载请注明原文链接:https://www.cnblogs.com/tangToms/articles/14248587.html

浙公网安备 33010602011771号