python网络爬虫-基础知识、库

python-网络爬虫

基础网络知识

json(轻量级的数据交换格式。。没有带s的方法都是涉及到文件的操作)

一、json.dumps(i): 将特定格式的数据进行字符串化的操作

比如列表字典都可以进行字符串化操作然后写入json的file;而且如果是要写入json文件就必须要进行dumps操作;
  
 

二、json.dump():将数据转换成str格式,添加了将数据写入json文件的一个操作步骤

son.dump(data, file-open,ascii=False),可以包含三个属性,第三个ascii是用来避免出现unicode写入的乱码的;


 

三、json.loads():将字符型数据转换成原来的数据格式,诸如列表和字典



四、json.load():从json文件中读取数据,json.load(file-open)即可,这样可以还原在json文件中的原本的数据格式,诸如列表或者字典;file在open的时候最好是注意用encoding=‘utf-8’的编码,这样出来的数据就是原来的数据,而不会出现乱码;




URL(Uniform Resource Locator,统一资源定位符):网络地址

URL格式:protocol:// hostname[:port] /path/[;parameters] [?query]#fragment
中括号为可选选

第一部分是协议:http、https、ftp、file

第二部分是存放资源的服务器的域名系统或IP地址(有时候要包含端口号,各种传输协议都有默认的端口号,http默认为80)

第三部分是资源的具体位置(如目录或文件名)



网站检查

method(network-status右键显示method,再点击一次按钮类请求):


post(提交):向指定服务器提交被处理的数据

headers:

1)General:
远程地址(端口号)、请求地址(url),请求方法(post)

2)Request Headers:
通过User-Agent来判断是否是浏览器访问(或是代码访问)

3)From data(表单数据):post提交的主要内容


get(获取):是指服务器请求获得数据



隐藏(修改Headers)

1)通过Request的headers参数修改

2)通过Request.add_header(key,value)方法修改

一个请求修改User-Agent

初版隐藏:

   #伪装 从User-Agent得知
        header={"User-Agent":" Mozilla/5.0 (Windows NT 6.1; Win64; x64) "}


        #封装
        response=request.Request(url=base_url,headers=header,data=data_str) 
           #创建一个Request对象



        
        req=request.urlopen(response).read().decode("utf-8")   

  #响应对象,read成网页内容,decode返回req字符串


网页爬取与代理

未解码版:

import urllib.request as r
response = r.urlopen('http://www.fishc.com')
response.read()

代理(用多个其他的服务器IP访问网页,并获取数据)

1.参数是一个字典{‘类型’,‘代理ip:端口号’}
键:代理类型(如http) 值:对应的IP

proxy_suppot = urllib.request.ProxyHandler({})


2.定制和创建一个opener
opener = urllib.request.build_opener(proxy_support)

平常的访问也是调用了opener,在这里我们定制一个opener,用代理ip去访问网页


3.安装opener(永久用代理) urllib.request.install_opener(opener)

4.调用opener(使用特殊的opener来打开网页)
opener.open(url)


初版代理:

import urllib.request as r

url='https://www.kuaidaili.com/free/'

proxy_support = r.ProxyHandler({'http':'58.22.177.200:9999'})

opener = r.build_opener(proxy_support)

r.install_opener(opener)

response = r.urlopen(url)

html = response.read().decode('utf-8')

print(html)


初版代理+隐藏

opener.addheaders[(key,value)]

例如:opener.addheaders[('User-Agent','*************')]



网页内容下载

图片下载初版:

import urllib.request as r

req =r.Request('http://placekitten.com/g/500/600')

response = r.urlopen(req)

cat_img = response.read()

with open('cat_500_600.jpg','wb') as f:
      f.write(cat_img)


# fp=open(文件)等同于 with open(文件名) as fp 




常用包、库

urllib包(url+lib,主要使用parse和request模块)

parse模块

urlencode():将字典转换为url格式



request模块

urlopen(url,)data=None):打开URL网址,返回响应对象(http.client.HTTPResponse对象)

url参数可以是一个字符串url或者是一个Request对象

data为None时用get获取,data赋值时为post提交

响应对象大概包括read()、readinto()、getheader()、getheaders()、fileno()、msg、version、status、reason、debuglevel和closed函数,

使用read()函数 返回未解码的网页内容(如字节流或图片)

read()得到内容后用decode()函数使用对应的解码方式,返回相应的对象(如utf-8 返回字符串)


geturl()、getcode()获取响应频率、info()



Request:信息更完善的请求对象,包括headers(请求头)等信息
request = urllib.request.Request(url = url,data = data, /
headers = headers,method = 'POST')

data参数要求bytes(字节流)类型,如果是一个字典,先用urllib.parse.urlencode()编码。
data为空,method默认为get。data不为空,method默认为post

data = urllib.parse.urlencode(字典).encode('utf-8')




requests模块(Python第三方库,处理URL资源更方便)

https://www.cnblogs.com/lei0213/p/6957508.html

requests是用python语言基于urllib编写的,采用的是Apache2 Licensed开源协议的HTTP库,requests比urllib更加方便

request支持HTTP连接保持和连接池,支持使用cookie保持会话,支持文件上传,支持自动响应内容的编码,支持国际化的URL和POST数据自动编码。


requests.get()

requests.get(url,params = None,headers = None,cookies = None,auth = None,timeout =无)
发送GET请求。 返回response对象。

参数:
url - 新的Request对象的URL。
params - (可选)使用请求发送的GET参数字典。(如需要的data数据)

头文件headers - (可选)使用请求发送的HTTP头文件字典。

如 : headers = { 'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) ' }


Cookie - (可选)使用请求发送的CookieJar对象。
auth - (可选)AuthObject启用基本HTTP身份验证。
超时 - (可选)描述请求超时的浮点数。

不带参数:requests.get(url)

带参数:requests.get(url=? params=字典 # 带参数的get请求


请求方式

requests.post("http://httpbin.org/post")
requests.put("http://httpbin.org/put")
requests.delete("http://httpbin.org/delete")
requests.head("http://httpbin.org/get")
requests.options("http://httpbin.org/get")
requests.post()

A:application/x-www-form-urlencoded ==最常见的post提交数据的方式,以form表单形式提交数据

url = 'http://httpbin.org/post'
data = {'key1':'value1','key2':'value2'}
r =requests.post(url,data)

B:application/json ==以json格式提交数据

url_json = 'http://httpbin.org/post'
data_json = json.dumps({'key1':'value1','key2':'value2'})  
#dumps:将python对象解码为json数据

r_json = requests.post(url_json,data_json)


C:multipart/form-data ==一般使用来上传文件(较少用)

url = 'http://httpbin.org/post'
files = {'file':open('E://report.txt','rb')}
r = requests.post(url,files=files)



response模块(requests.response)

是requests.reponse 对象
打印response:<Response [200]>

request.content与request.text

response.text :返回的是一个 unicode 型的文本数据 (可能是str类型),通常需要转换为utf-8格式,否则就是乱码

response.enconding = "utf-8'

response.content :返回的是 bytes 型的二进制数据 (取图片,视频,文件),
直接写入不需要解码,想看的话需要decode成utf-8格式。

response.content.decode() 返回utf-8的字符串(可能是按照默认解码方式)



response是一个响应对象,post也有内容



response.json()

等同于json.loads(response.text)方法 (字符串转换成字典)


内在属性

cookie的一个作用就是可以用于模拟登陆,做会话维持

#打印请求页面的状态(状态码)
print(type(response.status_code),response.status_code)

#打印请求网址的headers所有信息
print(type(response.headers),response.headers)

#打印请求网址的cookies信息
print(type(response.cookies),response.cookies)

#打印请求网址的地址
print(type(response.url),response.url)

#打印请求的历史记录(以列表的形式显示)
print(type(response.history),response.history)

#解码方式
response.encoding

状态码200正常:

#如果response返回的状态码是非正常的就返回404错误
if response.status_code != requests.codes.ok:
    print('404')
 
 
#如果页面返回的状态码是200,就打印下面的状态
response = requests.get('http://www.jianshu.com')
if response.status_code == 200:
    print('200')




代理

1、设置普通代理

import requests
 
proxies = {
  "http": "http://127.0.0.1:9743",
  "https": "https://127.0.0.1:9743",
}
response = requests.get("https://www.taobao.com", proxies=proxies)
print(response.status_code)

2、设置用户名和密码代理
import requests
 
proxies = {
    "http": "http://user:password@127.0.0.1:9743/",
}
response = requests.get("https://www.taobao.com", proxies=proxies)
print(response.status_code)

设置socks代理

安装socks模块 pip3 install ‘requests[socks]’

import requests
 
proxies = {
    'http': 'socks5://127.0.0.1:9742',
    'https': 'socks5://127.0.0.1:9742'
}
response = requests.get("https://www.taobao.com", proxies=proxies)
print(response.status_code)



超时设置、认证设置

超时设置:

  通过timeout参数可以设置超时的时间
import requests
from requests.exceptions import ReadTimeout
 
try:
    # 设置必须在500ms内收到响应,不然或抛出ReadTimeout异常
    response = requests.get("http://httpbin.org/get", timeout=0.5)
    print(response.status_code)
except ReadTimeout:
    print('Timeout')

认证设置:

如果碰到需要认证的网站可以通过requests.auth模块实现

import requests
from requests.auth import HTTPBasicAuth
<br>#方法一
r = requests.get('http://120.27.34.24:9001', auth=HTTPBasicAuth('user', '123'))<br>
#方法二<br>r = requests.get('http://120.27.34.24:9001', auth=('user', '123'))
print(r.status_code)





证书

在请求https时,request会进行证书的验证,如果验证失败则会抛出异常

关闭证书验证:

import requests
# 关闭验证,但是仍然会报出证书警告
response = requests.get('https://www.12306.cn',verify=False)
print(response.status_code)


消除验证证书的警报:

from requests.packages import urllib3
import requests
 
urllib3.disable_warnings()
response = requests.get('https://www.12306.cn',verify=False)
print(response.status_code)


手动设置证书:
response = requests.get('https://www.12306.cn', cert=('/path/server.crt', '/path/key'))
print(response.status_code)




lxml库是Python的一个解析库,支持HTML和XML的解析,支持XPath。 lxml与xpath用于确定文档中某部分位置

安装,cmd下:pip install lxml

引入etree:from lxml import etree

将字符串等转换为html对象,并自动补全结点:html = etree.HTML(text)

读取文件为html对象:html = etree.parse('./test.html',etree.HTMLParser())

将html文件转为字符串并解码输出:

result = etree.tostring(html)

print(result.decode('UTF-8'))


XPath即为XML路径语言,它是一种用来确定XML/HTML文档中某部分位置的语言。

html对象就是xpath解析对象,返回一个列表


extract():
item['name'] = each.xpath("./a/text()").extract()[0]

each                               html文档

each.xpath("./a/text()")  xpath解析返回的是一个选择器列表

extract()                         转换为Unicode字符串列表

[0]                                  列表第一个位置  



selenium 库:Web应用程序测试工具,Selenium测试直接运行在浏览器中,就像真正的用户在操作一样。




正则表达式(描述复杂规则的工具,re模块)

如想办法直接找到想要的数据(例如网页链接),而不是通过静态的前端标签
正则表达式以字符串的形式来描述

语法规则详细列表(小甲鱼)

re模块

re.search(pattern, string, flags=0)

用于在字符串中搜索正则表达式模式 第一次出现的位置
也就是返回模式字符串在原始字符串中的第一个字符位置,没有返回None


pattern : 正则中的模式字符串(漠视规则)。r模式字符串,转义python字符串,防止出错’`

string : 要被查找替换的原始字符串。

flags : 标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。
正则表达式默认区分大小写模式(大小写敏感模式)

re.match()方法要求必须从字符串的开头进行匹配,如果字符串的开头不匹配,整个匹配就失败了;



元字符(具有特殊含义的字符)

'.':表示除了'\'以外的任何字符

'\':转义正则表达式字符(普通变特殊,元字符变普通)
或引用序号对应的子组所匹配的字符串
'\数字':两种表示方案(根据数字的取值)
1)1-99:引用序号对应的子组所匹配的字符串

r'(fishC)\1' == r'fishCfishC'   \1表示重复第一个子组的内容

2)0、三位数:8进制数(表示这个8进制数对应的ASCII码的字符)
'\060' == '0' 因为060是‘0’的Ascii码的八进制形式


():子组(把一个东西当做整体),匹配圆括号中的正则表达式,或者指定一个子组的开始
注:子组的内容可以在匹配之后被 \数字 再次引用

'|':逻辑或

>>> re.search(r'fish(c|d)','fishc')
<re.Match object; span=(0, 5), match='fishc'>
>>> re.search(r'fish(c|d)','fishd')
<re.Match object; span=(0, 5), match='fishd'>

^:(脱字符)匹配输入字符串的开始位置(模式串必须在字符串的开始位置)
如果设置了 re.MULTILINE 标志,^ 也匹配换行符之后的位置


$:匹配输入字符串的结束位置
如果设置了 re.MULTILINE 标志,$ 也匹配换行符之前的位置


{min,max}表示模式串匹配前面的子表达式(字符、子组)的次数(min-max)

>>> re.search(r'ab{3}c','abbbc')
<re.Match object; span=(0, 5), match='abbbc'>

#匹配3-10次
>>> re.search(r'ab{3,10}c','abbbbbbbc')
<re.Match object; span=(0, 9), match='abbbbbbbc'>

匹配1000以内的数字字符串
>>> re.search(r'\d{0,3}','188')
<re.Match object; span=(0, 3), match='188'>

1000以内的字符串匹配三次(***.***.***.***)
re.search(r'(([01]\d\d|2[0-4]\d|25[0-5])\.){3}([01]\d\d|2[0-4]\d|25[0-5])','192.168.1.1')

ip地址匹配
>>> re.search(r'(([01]{0,1}\d{0,1}\d|2[0-4]\d|25[0-5])\.){3}([01]{0,1}\d{0,1}\d|2[0-4]\d|25[0-5])','192.168.1.1')
<re.Match object; span=(0, 11), match='192.168.1.1'>

‘*’:匹配前面的子表达式零次或多次,等价于 {0,}

'+':匹配前面的子表达式一次或多次,等价于 {1,}

'?':匹配前面的子表达式零次或一次,等价于 {0,1}

默认情况下 *、+ 和 ? 的匹配模式是贪婪模式(即会尽可能多地匹配符合规则的字符串);
*?, +?, ?? 表示启用对应的非贪婪模式。

>>> re.search(r'.+','i love you')
<re.Match object; span=(0, 10), match='i love you'>

>>> re.search(r'.+?','i love you')
<re.Match object; span=(0, 1), match='i'>



[]:字符类(字符集合),匹配字符类中的任何字符,返回匹配串 符合字符类中字符 的第一个位置
除了几个特殊字符,其他符号都当作普通字符来对待(如.

注1:连字符 - 如果出现在字符串中间表示字符范围描述;如果如果出现在首位则仅作为普通字符
注2:特殊字符仅有反斜线 \ 保持特殊含义,用于转义字符。其它特殊字符如 *、+、? 等均作为普通字符匹配
注3:脱字符 ^ 如果出现在首位则表示匹配 不包含在其中的任意字符(相当于取反);如果 ^ 出现在字符串中间就仅作为普通字符匹配

>>> re.search(r'[iloveILOVE]','ilove 123')
<re.Match object; span=(0, 1), match='i'>

>>> re.search(r'[a-z]','ilove 123')
<re.Match object; span=(0, 1), match='i'>

>>> re.search(r'[0-9]','ilove 123')
<re.Match object; span=(6, 7), match='1'>

如匹配0-255的数字字符串

该方法实际是匹配的第一个字符
>>> re.search(r'[0-255]','188')
<re.Match object; span=(0, 1), match='1'>

等同于
>>> re.search(r'[0-2]','188')
<re.Match object; span=(0, 1), match='1'>


该方法匹配三个字符类的字符串(0-300>>> re.search(r'[0-2][0-9][0-9]','188')
<re.Match object; span=(0, 3), match='188'>

该方法匹配0-255字符串(|表示或)
>>> re.search(r'[01]\d\d|2[0-4]\d|25[0-5]','188')
<re.Match object; span=(0, 3), match='188'>

匹配1000以内的数字字符串
>>> re.search(r'\d{0,3}','188')
<re.Match object; span=(0, 3), match='188'>


特殊字符(被'\'转义的普通字符)

'\d'表示匹配数字

>>> re.search(r'\d\d\d','ilove 123')
<re.Match object; span=(6, 9), match='123'>





re.findall():找到所有匹配的字符串并打包成列表返回

不只是找到第一个匹配的字符串然后返回

>>> re.findall(r'[a-z]','FIshc.com')

['s', 'h', 'c', 'c', 'o', 'm']

匹配规则为a-z,连续匹配到了六个字符串(特殊地,这里都是一个字符的字符串)



xpath:对HTML文档进行搜索


https://blog.youkuaiyun.com/qq_25343557/article/details/81912992?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task

html对象就是xpath解析对象

xpath常用规则(返回list)

/用于获取直接子节点,//用于获取子孙节点:

表达式	描述
nodename	选择这个节点名的所有子节点
/	从当前节点选择直接子节点
//	从当前节点选取子孙节点

.	选择当前节点
…	选取当前节点的父节点
@	选取属性

引入:from lxml import etree

例子:

/html/head/title:选取html文档中<head>标签内的<title>元素

/html/head/title/text():选择上面提到的<title>元素的文字

//td:选择所有的<td>元素

//div[@class="mine"]:选取所有具有class=“”mine“”属性的div元素

获取所有节点:

result = html.xpath('//*')
'//'表示获取当前节点子孙节点,'*'表示所有节点,'//*'表示获取当前节点下所有节点
for item in result:
    print(item)

获取所有特定节点,如获取所有的li节点。
result = html.xpath('//li')#将*改为li,表示只获取名称为li的子孙节点
#返回一个列表
for item in result:
    print(item)

获取所有某特定节点下的子节点(被父结点包围),如li结点下的a结点
result = html.xpath('//li/a')#//li选择所有的li节点,/a选择li节点下的直接子节点a
for item in result:
    print(item)

根据属性获取特定节点:

result = html.xpath('//li[@class="item-3"]')
#返回class属性为item-3的li结点(列表形式)

获取特定属性
html.xpath('//ul[@id="pins"]/li/a/@href') 
#获取id为pins的ul结点 下的子节点li 下的子节点 的href属性的值



异常处理

URLError:访问网页异常

import urllib.request as r
import urllib.error

req=r.Request("http://www/ooxx-fishc.com")

try:
    r.urlopen(req)
except urllib.error.URLError as e:
    print(e.reason)

HTTPError:状态码异常
http状态码大全

400-499:问题来自于客户端
500-599:服务器问题

except urllib.error.HPPTError as e:
 print(e.reason)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值