美文网首页
【python】爬虫

【python】爬虫

作者: 我写的BUG代码少 | 来源:发表于2020-04-14 13:35 被阅读0次

B站视频链接:https://www.bilibili.com/video/BV1FJ411L7Hn

爬虫

一.基本指令

import requests
#1.定义URL
url='https://www.baidu.com'

#2.发起get请求
res=requests.get(url)

#3.获取响应结果
res.status_code #200代表成功 
res.url #请求的url地址
res.content#b'...' 二进制文本流
res.content.decode('utf-8')
res.text    #获取响应的内容
res.headers     #响应头信息#{'Cache-Control': 'private, no-cache, no-store, proxy-revalidate, no-transform', 'Connection': 'keep-alive', 'Content-Encoding': 'gzip', 'Content-Type': 'text/html', 'Date': 'Mon, 13 Jan 2020 02:11:01 GMT', 'Last-Modified': 'Mon, 23 Jan 2017 13:24:45 GMT', 'Pragma': 'no-cache', 'Server': 'bfe/1.0.8.18', 'Set-Cookie': 'BDORZ=27315; max-age=86400; domain=.baidu.com; path=/', 'Transfer-Encoding': 'chunked'}
res.request.headers#请求的头信息#{'User-Agent': 'python-requests/2.22.0', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Connection': 'keep-alive'}

二.GET请求

#1.定义url
url='https://www.xicidaili.com/nn'

#2.自定义请求头信息--从浏览的网页中获取
headers={
    'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36 Edge/18.18362'
}
res=requests.get(url=url,headers=headers)

#3.响应成功后把响应内容写入文件中
code=res.status_code
if code==200:
    with open('./test.html','w',encoding='utf-8') as fp:
        fp.write(res.text)

三.POST请求

#1.定义url
u='https://fanyi.baidu.com/sug'

#2.定义请求信息头
headers={
    'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36 Edge/18.18362'
}

#3.post发送的数据
data={'kw':'你好'}

#4.发送请求
res=requests.post(url=u,headers=headers,data=data)

#5.接受返回数据
code=res.status_code
if code==200:
    print('请求成功')
    data=res.json()  #数据是json格式的
    if data['errno']==0: 
        print('响应成功')
        print(data)
        print(data['data'][0]['k']) #返回数据中,data list中第一个字典
        v=data['data'][0]['v']
        print(v.split(';')[-2])

四.主动添加-携带cookie

#1.定义url
u='https://fanyi.baidu.com/sug'

#2.定义请求信息头
headers={
    'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36 Edge/18.18362',
    'cookie':''  #浏览器中获取cookie信息
}

#3.post发送的数据
data={'kw':'你好'}

#4.发送请求
res=requests.post(url=u,headers=headers,data=data)

#5.接受返回数据
code=res.status_code
if code==200:
    print('请求成功')
    data=res.json()  #数据是json格式的
    if data['errno']==0: 
        print('响应成功')
        print(data)
        print(data['data'][0]['k']) #返回数据中,data list中第一个字典
        v=data['data'][0]['v']
        print(v.split(';')[-2])      

五.python自动获取cookie信息

使用requests中的session方法

#1.定义URL
url='http://'  #最终请求目标地址
login_url='http://' #登录后-登录请求的URL//Headers-General-URL

#2.请求头信息
headers={
    'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36 Edge/18.18362'
}

#3.使用session方法
'''
如果需要爬虫程序主动记录并携带cookie,那么在使用requests前需先调用session方法
并且使用session方法返回的对象发送请求即可
'''
req=requests.session()

#4.发起登录请求
##登录时的数据//Form Data
data={
'account':'',
'password':'',
'remember':'',
'url_back':'' 
}
##
res=req.post(url=login_url,headers=headers,data=data)

#5.判断状态并写入
code=res.status_code
if code==200:
    #发起新请求,去获取目标数据
    res=req.get(url=url,headers=headers)
    with open('test.html','w') as fp:
        fp.write(res.text)

六.Xpath解析数据

#1.【在python代码中解析字符串】
from lxml import etree
#1.1 获取源代码
text='''
#访问网页-源代码
'''
#1.2 使用etree解析html字符串
html=etree.HTML(text)
#1.3 提取数据
r=html.xpath('/html/body/li/a/text()') #获取指定标签body下的li标签下的数据
print(r)
#获取页面所有li标签下的数据 :r=html.xpath('//li/a//text()') 
#获取指定标签下的li数据:r=html.xpath('//div[@class='teacher']//li/a/text()')


#2.【读取一个html文件并解析】
###先把网页代码粘贴到html文件中
html=etree.parse('./test.html', etree.HTMLParser())
r=etree.tostring(html)
print(r.decode('utf-8'))

七.Xpath实战登录

import requests
from lxml import etree
#封装类。进行网站的登录和订单的获取
class Lmonkey():
    loginurl=''
    orderurl=''
    headers={
        'User-Agent':''
    }
    #请求对象
    req=None
    #token口令
    token=''
    #订单号
    ordercode=0
    #初始化方法
    def __init__(self):
        #请求对象的初始化
        self.req = requests.session()
        if self.getlogin():
            if self.postlogin():
                self.getorder()
    #get 登录页面 获取_token
    def getlogin(self):
        #1.get请求 login页面,设置cookie,获取_token
        res=self.req.get(url=self.loginurl,headers=self.headers)
        if res.status_code==200:
            print('get登录页面请求成功')
            html=etree.HTML(res.text)
            self.token=html.xpath('//input[@name="_token"]/@value')[0]
            print('token获取成功')
            return True
        else:
            print('请求错误')
    #post 请求登录 设置cookie
    def postlogin(self):
        uname=input('手机号:')
        passw=input('密码:')
        data={
            '_token':self.token,
            'username':uname,
            'password':passw
        }         
        #发起post请求
        res=self.req.post(url=self.loginurl,headers=self.headers,data=data)
        if res.status_code==200 or res.status_code==302:
            print('登录成功')
            #请求订单数据
            return True
    
    #get 请求账户中心 获取默认订单号
    def getorder(self):
        #3.get请求,账户中心,获取默认订单号
        pass
        res=self.req.get(url=self.orderurl,headers=self.headers)
        if res.status_code==200:
            print('账户中心请求成功,正在解析数据')
            html=etree.HTML(res.text)
            r=html.xpath('//div[@class="avatar-content"]//small/@text()')
            print(r)
            self.ordercode=r
obj=Lmonkey()
#1.get请求 login页面,设置cookie,获取_token
#2.post请求 提交登录数据,进行登录,并设置cookie
#3.get请求,账户中心,获取默认订单号

八.beautiful soup

1.基本语法

from bs4 import BeautifulSoup
#1.定义html文档内容
html_doc='''
<html><head><title abc='123'>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 was three little sisters; and their names were
<a herf='http://example.com/elsie' class='sister' id='link1'>Elsie</a>,
<a herf='http://example.com/lacie' class='sister' id='link2'>Lacie</a> and
<a herf='http://example.com/tillie' class='sister' id='link3'>Tillie</a>;
and they lived at the botom of a well.</p>
</ class='story'>...</p>
'''
#2.创建一个BeautifulSoup对象,建议手动指定解析器:
soup=BeautifulSoup(html_doc,'lxml')

#2.1 通过tag标签对象获取文档数据
r=soup.title #title标签(元素)
r=soup.title['abc']#结果123
r=soup.p #第一个p标签结果--<p class='title'><b>The Dormouse's story</b></p>
r=soup.p['class']#p元素的class属性--['title']
r=soup.p.b#p标签下的b标签--<b>The Dormouse's story</b>
r=soup.title.text #获取title下的文本--结果The Dormouse's story
r=soup.p.parent.name#p元素的父节点的标签--body

#2.2 通过搜索获取页面中的元素(使用find和find_all方法进行查找
'''
- find和find_all可以有多个搜索条件叠加,比如find('a',id='link3',class_='sister')
- find 返回的是一个bs4.element.Tag对象,这个对象可以进一步进行搜索。如果有多个满足的结果,find只返回第一个;如果没有,返回None
- find_all 返回的是一个由bs4.element.Tag对象组成的list,不管找到几个或是没找到,都是list
'''
soup.find(id='link3') #id为link3的元素
'''
<a herf="http://example.com/tillie" class='sister' id='link3'>Tillie</a>
soup.find_all('a')#所有a元素
[<a herf="http://example.com/elsie" class='sister' id='link1'>Elsie</a>,
<a herf="http://example.com/lacie" class='sister' id='link2'>Lacie</a> and
<a herf="http://example.com/tillie" class='sister' id='link3'>Tillie</a>]
'''
x=soup.find(class_='story')
x.get_text() #仅可见文本内容
#'Once upon a time there was three little sisters; and their names were\nElsie,\nLacie and\nTillie;\nand and they lived at the botom of a well.'

#2.3 css选择器

soup.select('title') #通过tag查找

soup.select('html head title') #通过tag逐层查找

soup.select('.sister') #通过class查找

soup.select('#link1,#link2') #通过id查找

soup.select('p #link1') #组合查找

soup.select('html body p') #通过空格 层级关系获取元素

soup.select('a,title') #通过逗号,并列关系获取元素

soup.select('head>title') #查找直接子标签
soup.select('p>#link1')
soup.select('p>a:nth-of-type(2)')#nth-of-type是css选择器

soup.select('#link1~.sister') #查找兄弟节点(向后查找)
soup.select('#link1+.sister')

soup.select('a[href="http://example.com/1"]') #通过属性查找

soup.select('a[href^="http://example.com/"]') #^以xx开头

soup.select('a[href*=".com/"]') #*包含

soup.select('[name]') #查找包含指定属性的标签

soup.select_one('.sister') #查找第一个元素

2.bs4实战

2.1 原始代码

#--学习猿地-猿圈
'''
分析爬取的数据
数据源地址:http://www,lmonkey.com/t
数据内容:文章标题,文章的链接,作者,发布时间
工具:python,requests,bs4
'''
import requests,json
from bs4 import BeautifulSoup
#1.定义请求的URL和请求头
url='http://www,lmonkey.com/t'
headers={
    'user-agent':''
    }
#2.发送请求
res1=requests.get(url=url,headers=headers)
#3.判断请求是否成功,并获取请求源代码
if res1.status_code==200:
    #4.解析数据
    soup=BeautifulSoup(res1.text,'lxml')
    #---获取页面中所有文章
    divs=soup.find_all('div',class_='list-group-item list-group-item-action p-60')
    varlist=[]
    for i in divs:
        r=i.find('div,class_="topic_title"')
        if r:  #如果r结果为真,打印内容
            vardict={'title':r.text.split('\n')[0],
            'url':i.a['href'],
            'author':i.strong.a.text,
            'pubdate':i.span['title']
            }
            varlist.append(vardict)
            print(varlist)
    #5.写入数据
    with open('./yq.json','w') as fp:
        json.dump(varlist,fp)

2.2 优化代码

#封装类
class Bs4Yq():
    #定义属性:url&请求头
    url='http://www,lmonkey.com/t'
    headers={
    'user-agent':""
    }
    #响应源代码的存放位置
    res2_html = None

    #存储解析后的json数据
    varlist=[]

    #初始化方法
    def __init__(self):
        #发起一个请求
        res2=requests.get(self.url,headers=self.headers)
        if res2.status_code==200:
            self.res2_html=res2.text
            if self.ParseData():
                self.WriteJson()
                print('数据成功,写入文件')
        else:
            print('请求失败')
    
    #解析html数据
    def ParseData(self):
        soup=BeautifulSoup(self.res2_html,'lxml')
        try:
            #---获取页面中所有文章
            divs=soup.find_all('div',class_='list-group-item list-group-item-action p-60')
            for i in divs:
                r=i.find('div,class_="topic_title"')
                if r: #如果r结果为真,打印内容
                    vardict={'title':r.text.split('\n')[0],
                        'url':i.a['href'],
                        'author':i.strong.a.text,
                        'pubdate':i.span['title']
                    }
                    self.varlist.append(vardict)
            return True
        except:
            return False
    #写入json数据
    def WriteJson(self):
        if self.varlist !=[]:
            try:
                with open('./yq.json', 'w') as fp:
                    json.dump(self.varlist,fp)
                return True
            except:
                return False
        else:
            print('无法获取当前的解析数据')

Bs4Yq() #调用

九.正则表达式

正则表达式:一种规则(由各类字符组成),使用这种规则能对文本内容完成搜索/匹配/替换的功能

正则表达式的组成
普通字符:大小写,数字,符号
转义字符:\w \W \d \D \s \S...
特殊字符:. * ? + $ ^ [] () {}
匹配模式:I U ...

1.使用方法

import re
#定义字符串
vars='iloveyou521tosimida'
#定义正则表达式
reg='\d'
#调用
res=re.findall(reg,vars)

2.re模块的相关函数

  • re.match()
    • 从头开始匹配
    • 要么第一个就符合,要么不符合
    • 匹配成功则返回match的对象,否则返回none
    • 可以使用group()/span()方法
      res=re.match(reg,vars)
      res.group() #获取一个返回的数据结果
      res.groups() #获取多个数据结果
      res.span() #获取结果的下标区间
      
  • re.search()
    • 从字符串开头到结尾进行搜索式匹配
    • 匹配成功则返回match的对象,否则返回none
    • 可以使用group()/span()方法
  • match()和search()方法的区别:
    • match() 是从字符串的开头进行匹配,如果开始就不符合正则要求,则匹配失败返回none
    • search() 是从字符串开始位置一直搜索到字符串的最后,如果在整个字符串都没有匹配到,则失败返回none
  • re.findall()
    • 按照正则表达式的规则在字符串中匹配所有符合规则的元素,返回一个列表,如果没有找到则返回空列表
  • re.finditer()
    • 按照正则表达式的规则在字符中匹配所有符合规则的元素,返回一个迭代器
      res=re.finditer(reg,var)
      res1=list(res)
      print(res1)
      
  • re.sub() 搜索替换
    • 参数
      • pattern:正则表达式的规则,匹配需要被替换的字符串
      • repel:替换后的字符串
      • string:被替换的原始字符串
      import re
      varstr=''
      reg=''
      res=re.sub(reg,'替换内容',varstr)
      
  • compile()
    • 定义正则表达式模式
    • 可以将正则表达式定义为“正则对象”,使用正则对象直接操作
    • 大量数据适用这种方法
      reg=re.compile('\d{3}')
      res=reg.findall(string=vars)
      

3.正则表达式的定义和规则

  • (1)普通字符:大小写,数字,符号
  • (2)转义字符:\w \W \d \D \s \S...
reg='\w' #单个的 字母/数字/下划线
reg='\W' #单个的 非字母/数字/下划线
reg='\d' #单个的 数字
reg='\D' #单个的 非数字
reg='\s' #单个的 空格符/制表符
reg='\S' #单个的 非空格符/制表符
reg='\w\w\w\w\d' #组合使用
  • (3)特殊字符:. * ? + $ ^ [] () {}
reg='.'      #单个的 任意字符 除了换行符之外
reg='\w*'    #* 代表匹配任意次数      
             #特点:
             #--如果在匹配的开始处符合要求,则一直向后匹配,直到不符合匹配规则的结束,并返回前面符合规则的.
             #--如果在匹配的开始处,则直接返回,匹配到的次数为0     
reg='\w+'    #+ 至少匹配一次
reg='\w+?'   #? 拒绝贪婪==前面的匹配规则只要达成则返回
reg='\w{4}'  #{匹配次数} ;{2,5}匹配2-5次
reg='[a-z]'  #[] 匹配范围 #[a-z,A-Z,0-9,_]==\w
reg='\w(\d{4})' #() 代表子组,括号中的表达式首先作为整个正则的一部分,零位会把符合小括号中的内容单独提取
reg='^1\d{10}$' #^ 定义开头(开头是个1;$定义结尾(结尾是数字
reg=''
reg=''
  • (4)匹配模式:I U ...
vars='iLOVEyou'
reg='[a-z]{5,10}' #小写字母,连续5-10个
res=re.search(reg,vars,re.I)
    #用re.I模式忽略大小写

4.正则实战

import requests,re,json
#1.
url=''
headers={
    'user-agent':''
}

#2.
res=requests.get(url,headers=headers)

#3.判断并获取数据
if res.status_code==200:
    res_html=res.text
    #4.数据解析
    reg=''
    arr=re.findall(reg,res_html)
    titlelist=[i.strip() for i in arr] #去除空格

    reg1=''
    authorlist=re.findall(reg1,res_html)

    reg2=''
    datelist=re.findall(reg2,res_html)

    #5.压缩数据
    data=list(zip(titlelist,authorlist,datelist))
    
    #6.1常规方式 处理数据
    datalist=[]
    for i in data:
        res={'title':i[0],'author':i[1],'date':i[2]}
        datalist.append(res)
    
    #6.2其他方法
    datalist=[{'title':i[0],'author':i[1],'date':i[2]} for i in data]

    #7.数据入库
    with open('./data.json','w',encoding='utf-8') as fp:
        json.dump(datalist,fp)


相关文章

网友评论

      本文标题:【python】爬虫

      本文链接:https://www.haomeiwen.com/subject/cigzmhtx.html