Python小白入门的学习记录 8

283 阅读5分钟

爬虫

网络库

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

httpbin.org/get?a=123&b…

图片.png

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 图片.png

浏览器get请求

httpbin.org/get?a=123&b…

图片.png 其中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匹配空白的字符  替换为空值

图片链接和标题 图片.png 最后输出网址和标题

图片.png

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

所示结果:

image.png 救命 为什么标题不换行

爬取图片并保存

用函数的方法运行不出来 换成正则表达式的方法了

image.png 我们爬取该网址的图片

首先获取源代码,发现data-src中是图片链接

image.png

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('保存完毕')

所示结果:

image.png

到此我Python的课差不多学完的 但是我还是会继续看 很多东西我都不是很懂 应该说只知道个大概 最近开始上班了 但是希望还是坚持学习 很想以后去上海吃好吃的 啊 不是