python爬虫笔记01


前言

例如:爬虫技术基础--正则表达式。 用python模仿人点击浏览器,让web站点无法发现不是人。 反爬机制更新,程序失效。 python请求模块、解析模块丰富成熟,强大的scrapy网络爬虫框架。 1.通用网络爬虫:搜索引擎在用,遵守robots协议。百度快照是百度抓取的。 2.聚焦网络爬虫:面向需求,自己写的爬虫程序。

一、爬虫爬取步骤

1.确定URL地址 2.请求模块,得到网站的响应(网页源码) 3.从响应内容中提取自己需要的数据

二、请求模块

1.模块名:urllib.request 2.导入方式:res.read()结果是byte结构类型,res.read().decode('utf-8')是字符串类型
import urllib.request
或
from urllib import request
req = request.Request(url,headers=headers)
res = request.urlopen(req)
html = res.read().decode('utf-8')

3.headers
在谷歌地址栏输入 about:version,得到headers信息。才能获得真正的源代码。
代码如下:

import requests
import re
ur1 = "https://www.baidu.com/s?rtt=1&bsst=1&cl=2&tn=news&ie=utf-8&word=%E9%98%BF%E9%87%8C%E5%B7%B4%E5%B7%B4"
headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36'}
res = requests.get(ur1, headers = headers).text
p_info = '<p class="c-author">(.*?)</p>'
info = re.findall(p_info, res)
print(info)

4.从包引入headers
代码如下:

from fake_useragent import UserAgent
ua = UserAgent()
ua1 = ua.random
print(ua1)

三、编码模块

1.parse

urlencode({dict})
urlencode({'wd':'美女','pn':'20'})
# 编码后:'wd=%E8%D5XXX&PN=20'
from urllib import parse
params = {'wd':'赵丽颖'}
result = parse.urlencode(params)
url = 'https://www.baidu.com/s?' + result
print(result)
print(url)
#拼接url地址

#赵丽颖第二页
params = {'wd':'赵丽颖','pn':'10'}
result = parse.urlencode(params)
url = 'https://www.baidu.com/s?' + result
print(result)
print(url)


#url地址拼接
#1.字符串拼接:见上
#2.字符串格式化:用占位符实现
params = 'wd=%E7XXXX&pn=20'
url = 'https://www.baidu.com/s?%s'% params
print(url)
#3.format用法
url = 'https://www.baidu.com/s?{}'
params = 'wd=%E7XXXX&pn=20'
url = url.format(params)
print(url)

2.quote:

from urllib import parse
word = '美女'
result = parse.quote(word)
url = 'https://www.baidu.com/s?wd' + result
print(url)

baseurl = 'https://www.baidu.com/s?wd={}'
url = baseurl.format(result)
print(url)

3.解码:

unquote('%D3%F5XXX')

四、正则解析模块

1.re模块使用流程

import re
# r_list = re.findall('AB','ABCABCABCD')
# print(r_list)
# #(re.findall(pattern, string, flags=0)):返回string中所有与pattern相匹配的全部字符串,得到数组
# #['AB', 'AB', 'AB']
pattern = re.compile('AB')
r_list = pattern.findall('ABCABCABCD')
print(r_list)

2.写出匹配任意一个字符的正则表达式(两种方法)常用方法一

import re
pattern1 = re.compile('.',re.S)
pattern2 = re.compile('[\s\S]')

3.创建正则表达式(两种方法)常用方法二

import re
r_list = re.findall('正则表达式',html,re.S)
import re
pattern = re.compile(r'正则表达式',re.S)
r_list = pattern.findall(html)

输出结果是字符串,不是数字。

import re
content = 'hello 123 world 456 python基础135‘
result = re.findall('\d\d\d', content)
print(result)
符号功能说明
\d匹配一个数字字符
\w匹配一个字母、数字、或者下划线字符
\s匹配一个空白字符,e.g.换行符、制表符、普通空格
\S匹配一个非空白字符
\n匹配一个换行符,相当于按一次enter
\t匹配一个制表符,相当于按一次tab,或者8次空格
.匹配一个任意字符,换行符除外
*匹配0个或多个表达式
+匹配1个或多个表达式
?非贪婪限定符
()匹配括号内的表达式

五、贪婪匹配–(.*?)/非贪婪匹配

1.贪婪匹配

(.*?)

1.在整个表达式匹配成功的前提下,尽可能多的匹配 * + ?
2. 表示方式: .* .+ .?

用于获取文本A和文本B之间的所有内容
代码如下:

import re
res = '文本A百度新闻文本B,新闻标题文本A新浪财经文本B,文本A搜狗新闻文本B'
p_source = '文本A(.*?)文本B'
source = re.findall(p_source, res)
print(source)

2.非贪婪匹配

(.*?)

1.在整个表达式匹配成功的前提下,尽可能少的匹配 * + ?
2. 表示方式: .*? .+? .??

代码如下:

import re
pattern = re.compile('<div><p>.*?</p></div>',re.S)
r_list = pattern.findall(html)
print(r_list)

括号里放想要的内容,去掉 div> p>

import re
pattern = re.compile('<div><p>(.*?)</p></div>',re.S)
r_list = pattern.findall(html)
print(r_list)
s = 'A B C D'
p1 = re.compile('\w+\s+\w+')
print(p1.findall(s))
# 结果:['A B', 'C D']

p2 = re.compile('(\w+)\s+\w+')
print(p2.findall(s))
# 结果:
# 第一步:匹配完整['A B', 'C D']
# 第二步:匹配()['A', 'C']

p3 = re.compile('(\w+)\s+(\w+)')
print(p3.findall(s))
# 结果:
# 第一步:匹配完整['A B', 'C D']
# 第二步:匹配()[('A', 'B'), ('C', 'D')]
# 如果正则表达式中有两个以上元素,得到的是元祖套列表

六、实现步骤

1.查看是否为静态页面
右键-查看网页源代码-搜索数据关键字
2.找URL规律
第一页:http://tieba.baidu.com/f?kw=??&pn=0
第二页:http://tieba.baidu.com/f?kw=??&pn=50
第n页:pn=(n-1)*50
3.获取网页内容
4.提取所需数据
写正则表达式,来匹配数据
5.程序结构
1.使用随机User-Agent
2.每爬取1个页面后随机休眠一段时间
5.保存(本地文件、数据库)

import urllib.request
或
from urllib import request

七、练习-爬取百度贴吧

1.方法一代码示例

from urllib import request,parse
import random
import time
from useragents import ua_list

class TiebaSpider(object):
    def __init__(self):
        self.url = 'http://tieba.baidu.com/f?kw={}&pn={}'
        
    #获取响应内容
    def get_page(self,url):
        headers = {'User-Agent': random.choice(ua_list)}
        req = request.Request(url=url,headers=headers)
        res = request.urlopen(req)
        html = res.read().decode()
        return html
        
    #解析,提取数据
    def parse_page(self):

        pass
        
    #保存数据
    def write_page(self,filename,html):
        with open(filename,'w') as f:
            f.write(html)

    #入口函数
    def run(self):
        name = input('请输入贴吧名:')
        start = int(input('请输入贴吧起始页:'))
        end = int(input('请输入贴吧终止页:'))
        kw = parse.quote(name)
        #拼接+获取内容+保存
        for i in range(start,end+1):
            pn=(i-1)*50
            url = self.url.format(kw,pn)
            html = self.get_page(url)
            filename = '{}-第{}页.html'.format(name,i)
            self.write_page(filename,html)
            print('第%d页抓取成功'%i)

            #每爬取1个页面随机休眠1-3秒
            time.sleep(random.randint(1,3))
            
if __name__=='__main__':
    begin = time.time()
    spider = TiebaSpider()
    spider.run()
    stop = time.time()
    print('执行时间:%.2f' % (stop-begin))

2.方法二

#使用fake_useragent模块实现
from urllib import request,parse
import random
import time
from fake_useragent import UserAgent

class TiebaSpider(object):
    def __init__(self):
        self.url = 'http://tieba.baidu.com/f?kw={}&pn={}'

    def get_headers(self):
        ua = UserAgent()
        headers = {'User-Agent':ua.random}
        return headers
    #获取响应内容
    def get_page(self,url):
        headers = self.get_headers()
        #验证每一步的user agent不同
        #print(headers)
        req = request.Request(url=url,headers=headers)
        res = request.urlopen(req)
        html = res.read().decode()
        return html

    #解析,提取数据
    def parse_page(self):

        pass

    #保存数据
    def write_page(self,filename,html):
        with open(filename,'w') as f:
            f.write(html)

    #入口函数
    def run(self):
        name = input('请输入贴吧名:')
        start = int(input('请输入贴吧起始页:'))
        end = int(input('请输入贴吧终止页:'))
        kw = parse.quote(name)
        #拼接+获取内容+保存
        for i in range(start,end+1):
            pn=(i-1)*50
            url = self.url.format(kw,pn)
            html = self.get_page(url)
            filename = '{}-第{}页.html'.format(name,i)
            self.write_page(filename,html)
            print('第%d页抓取成功'%i)

            #每爬取1个页面随机休眠1-3秒
            time.sleep(random.randint(1,3))


if __name__=='__main__':
    begin = time.time()
    spider = TiebaSpider()
    spider.run()
    stop = time.time()
    #计算程序执行时间
    print('执行时间:%.2f' % (stop-begin))

八、练习-动物

代码如下:

import re
html = '''
<div class="animal">
    <p class="name">
        <a title="Tiger"></a>
    </p>
    <p class="content">
        Two tigers two tigers run fast
    </p>
</div>

<div class="animal">
    <p class="name">
        <a title="Rabbit"></a>
    </p>
    <p class="content">
        Small white rabbit white and white
    </p>
</div>
'''
# 去掉<div><p>,想要的内容放括号里
pattern = re.compile('<div class="animal">.*?title="(.*?)".*?"content">\n\s+(.*?)\n\s+</p>',re.S)
r_list = pattern.findall(html)
print(r_list)

# p3 = re.compile('(\w+)\s+(\w+)')
# print(p3.findall(s))
# 结果:
# 第一步:匹配完整['A B', 'C D']
# 第二步:匹配()[('A', 'B'), ('C', 'D')]
# 如果正则表达式中有两个以上元素,得到的是元祖套列表

print("动物名称:" + r_list[0][0])
print("动物描述:" + r_list[0][1])
print("动物名称:" + r_list[1][0])
print("动物描述:" + r_list[1][1])

更优:

import re
html = '''
<div class="animal">
    <p class="name">
        <a title="Tiger"></a>
    </p>
    <p class="content">
        Two tigers two tigers run fast
    </p>
</div>

<div class="animal">
    <p class="name">
        <a title="Rabbit"></a>
    </p>
    <p class="content">
        Small white rabbit white and white
    </p>
</div>
'''
re_bds = '<div class="animal">.*?title="(.*?)".*?'\
        'class="content">(.*?)</p>'
pattern = re.compile(re_bds,re.S)
r_list = pattern.findall(html)
print(r_list)

for r in r_list:
    print("动物名称:" + r[0].strip())
    print("动物描述:" + r[1].strip())
    print('*'*50)


总结

以上仅是爬虫基础的内容,简单介绍了爬虫的使用,后续将在应用中继续学习。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值