爬虫
网络库
urlib库,requests库(进行数据收集和下载)属于http协议常用库
urlib库
网页数据获取
from urllib import request # 导入
url = 'http://www.baidu.com' # 使用http网页协议
# 解析url显示内容 timeout指的超时时间秒为单位 超过1秒放弃打开网页
response = request.urlopen(url, timeout=1)
print(response.read().decode('utf-8')) #decode增加中文编码
所示结果;为该网页的源代码 过长则不展示
网页请求方式get和post
GET请求在URL中传送的参数是有长度限制的,而POST么有
get方式
httpbin.org 用get传输数据 a=123 b=456
from urllib import request
response2=request.urlopen('http://httpbin.org/get',timeout=1)
print(response2.read())
post方式
往服务器直接传递数据
from urllib import request
from urllib import parse #处理post数据
data=bytes(parse.urlencode({'world':'hello'}),encoding='utf8') #post请求需要先封装数据 parse.urlencode
response1=request.urlopen('http://httpbin.org/post',data=data) #data=data 指定传输数据
print(response1.read().decode('utf-8'))
HTTP头部信息
urllib请求的头部信息
import urllib
import socket
try:
response3 = urllib.request.urlopen('http://httpbin.org/get', timeout=0.1)
except urllib.error.URLError as e:
if isinstance(e.reason, socket.timeout):
print('TIME OUT')
所示结果:
头部信息headers
浏览器get请求
其中Firefox把url拒之门外
urllib模拟http请求的头部
#urllib伪装http头部
from urllib import request, parse
url = 'http://httpbin.org/post'#post请求方式
headers = { #头部请求信息
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
"Accept-Encoding": "gzip, deflate",
"Accept-Language": "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2",
"Host": "httpbin.org",
"Upgrade-Insecure-Requests": "1",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:88.0) Gecko/20100101 Firefox/88.0",
"X-Amzn-Trace-Id": "Root=1-60877b9b-49f02d0a503f6fcf37db876a"
}
dict = {
'name': 'value'
}
data = bytes(parse.urlencode(dict), encoding='utf8')
#字典方式不可以通过request发送给网站 要进行重新编码 parse.urlencode
req = request.Request(url=url, data=data, headers=headers, method='POST') #headers:头部信息通过 urllib传递给服务器
response = request.urlopen(req)
print(response.read().decode('utf-8'))
requests库
get请求
#requests库
#get请求
import requests
url='http://httpbin.org/get' #指定url
data={'key':'value','abc':'123'}#把要传递的数据写成字典形式
response=requests.get(url,data) #请求方式 requests.get 使用get方式请求url data属于字典类型不用处理
print(response.text) #返回显示
所示结果:
{
"args": {
"abc": "123",
"key": "value"
},
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"Host": "httpbin.org",
"User-Agent": "python-requests/2.25.1",
"X-Amzn-Trace-Id": "Root=1-60878341-629df56a093fb74d4a25243a"
},
"origin": "27.20.66.19",
"url": "http://httpbin.org/get?key=value&abc=123"
}
post请求
import requests
url='http://httpbin.org/get' #指定url
data={'key':'value','abc':'123'}#把要传递的数据写成字典形式
response=requests.post(url,data) #请求方式 requests.post 使用post方式请求url
print(response.json()) #返回显示 返回不仅可以用text文本格式也可以用json格式
所示结果:
b'{\n "args": {}, \n "headers": {\n "Accept-Encoding": "identity", \n "Host": "httpbin.org", \n "User-Agent": "Python-urllib/3.8", \n "X-Amzn-Trace-Id": "Root=1-6087826c-4c8b1b8214c30d0802c2adf2"\n }, \n "origin": "27.20.66.19", \n "url": "http://httpbin.org/get"\n}\n'
正则表达式爬取图片
import requests
import re
content=requests.get('http://www.cnu.cc/discoveryPage/hot-人像').text
print(content)
#网页原代码 html语言
#html中需要的图片链接
# < div class ="grid-item work-thumbnail" >
# < a href="(.*?)".*?title">(.*?)</div> #<a href="图片链接"> 需要提取的部分
# < div class ="author" > LynnWei < / div >
pattern = re.compile(r'<a href="(.*?)".*?title">(.*?)</div>', re.S) #获取html源代码中图片链接的部分()进行分组 用.*?进行链接的替换
results = re.findall(pattern, content) #利用findall匹配内容
print(results) #显示网址链接以及标题
#利用for循环 解析其元祖
for result in results:
url, name = result #网址链接赋给url变量 后面标题名称赋值给name变量
print(url, re.sub('\s', '', name)) #由于标题后有空格和\n 换行符 利用sub进行替换 \s匹配空白的字符 替换为空值
图片链接和标题
最后输出网址和标题
BeautifulSoup库
进行格式处理,属于xml格式处理库,代替正则解析html。
from bs4 import BeautifulSoup
html_doc = """
<html><head><title>The Dormouse's story</title></head>
<body>
<p class="title"><b>The Dormouse's story</b></p>
<p class="story">Once upon a time there were three little sisters; and their names were
<a href="http://example.com/elsie" class="sister" id="link1">Elsie</a>,
<a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and
<a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>;
and they lived at the bottom of a well.</p>
<p class="story">...</p>
"""
soup = BeautifulSoup(html_doc, 'lxml') # 导入html代码
print(soup.prettify()) # 进行格式html处理
#
# 获取title标签
print(soup.title)
#
# 获取title 标签里的内容
print(soup.title.string)
# 获得到p标签
print(soup.p)
# # 找到p标签class的名字
# print(soup.p['class'])
# # 找到第一个a标签
# print(soup.a)
# 找到所有的a标签
# print(soup.find_all('a'))
# 找到id为link3的的标签
print(soup.find(id="link3"))
#
# # 找到所有<a>标签的链接
# for link in soup.find_all('a'):
# print(link.get('href'))
#
# # 找到文档中所有的文本内容
# print(soup.get_text())
利用beautiful soup爬取新闻网站
tips: 获取指定class的标签的内容(用.)
获取指定id的标签的内容(用#)
(废话:这一点点 我研究了两天才搞出来 但是成就感满满 真的不怕失败就怕被失败打到 我也不会再害怕考科三了 不行我就一直考 总能过得)
import requests
url='http://news.sina.com.cn/china/'
web_data=requests.get(url)
web_data.encoding='utf-8'
soup=BeautifulSoup(web_data.text,'lxml')
# print(soup) #解析html网页
for news in soup.select('.main-content'): #找出所有class为main-content的元素,class名前面需要加点(.)
print([title.get('title') #title 为html新闻标题的头
for title in news.find_all('a') if title.get('title')]) #在所有a中找到新闻标题title
所示结果:
救命 为什么标题不换行
爬取图片并保存
用函数的方法运行不出来 换成正则表达式的方法了
我们爬取该网址的图片
首先获取源代码,发现data-src中是图片链接
import re
import requests
url = 'http://www.nipic.com/photo/lvyou/ziran/index.html'
#获取网页源代码
data=requests.get(url).text
#print('网页源码',data)
#图片正则表达式
regex=r'data-src="(.*?.jpg)"'
#re是一个列表
pa=re.compile(regex)#创建一个pa模板,使其符合匹配的网址
ma=re.findall(pa,data)#使用findall找到data中所有符合pa的对象,添加到re中并返回
print(ma) #提取出所有的图片网址
#讲ma中图片网址依次取出来
i=1
for img in ma:
i+=1
img=requests.get(img).content
print(str(i)+'.jpg正在保存。。。')
with open('../imgs/' + str(i) + '.jpg', 'wb') as f:
f.write(img)
print('保存完毕')
所示结果:
到此我Python的课差不多学完的 但是我还是会继续看 很多东西我都不是很懂 应该说只知道个大概 最近开始上班了 但是希望还是坚持学习 很想以后去上海吃好吃的 啊 不是