python爬虫基础

requests

requests.get()向服务器发送请求并服务器返回的值保存

import requests 
res=requests.get('https://img.kaikeba.com/web/kkb_index/img_index_logo.png') 
print(type(res))

res是requests.model.Response类,可以利用Response对象的属性和方法进行提取数据
response.status_code,检查请求是否成功

import requests 
res=requests.get('https://img.kaikeba.com/web/kkb_index/img_index_logo.png') 
print(res.status_code)

如果打印200,意味着请求成功,并将返回的数据赋给res。

响应状态码说明
1xx请求接收
2xx请求成功
3xx重定向
4xx客户端错误
5xx服务器错误

response.content,保存服务器返回的数据二进制内容

import requests
res=requests.get('https://img.kaikeba.com/web/kkb_index/img_index_logo.png')#发出请求,并把返回的结果放在变量res中
pic=res.content#把Reponse对象的内容以二进制数据的形式返回
photo = open('logo.png','wb')##图片内容需要以二进制wb读写
photo.write(pic)#获取pic的二进制内容
photo.close()#关闭文件

response.txt,把Response对象的内容以字符串的形式返回

import requests
res=requests.get('https://xiaoke.kaikeba.com/example/gexu/tengwanggexu.txt')
novel=res.text
print(novel)

response.encoding,指定Response对象的编码

import requests
res=requests.get('https://xiaoke.kaikeba.com/example/gexu/tengwanggexu.txt')
res.encoding='gbk'#定义Response对象的编码为gbk
novel=res.text
print(novel)

打印出的是乱码因为这篇文章原本编码是utf-8。一般而言requests库会自动判断编码类型,不需要指定。

bs4

获取数据

import requests
from bs4 import BeautifulSoup
res = requests.get('https://xiaoke.kaikeba.com/example/canteen/index.html')
soup = BeautifulSoup(res.text,'html.parser')#把网页解析为beautifulsoup对象,html.parser是解析器
print(type(soup)) #查看soup的类型,<class 'bs4.BeautifulSoup'>
print(soup) # 打印soup,与使用response.text打印出来的源代码是完全一样的

提取数据:find()与find_all(),以及Tag对象在这里插入图片描述

import requests
from bs4 import BeautifulSoup
res = requests.get('https://xiaoke.kaikeba.com/example/canteen/index.html')
html = res.text
soup = BeautifulSoup(html,'html.parser')
items = soup.find_all(class_='show-list-item') 
for item in items:
    print(item,type(item)) # 打印item,类型是'bs4.element.Tag'

Tag对象的三种常用属性与方法

属性/方法作用
Tag.find()和Tag.find_all()提取Tag中的Tag
Tag.text提取Tag中的文字
Tag[‘属性名’]输入参数:属性名,可以提取Tag中这个属性的值
import requests
from bs4 import BeautifulSoup
res = requests.get('https://xiaoke.kaikeba.com/example/canteen/index.html')
html = res.text
soup = BeautifulSoup(html,'html.parser') 
items = soup.find_all(class_='show-list-item')
for item in items:
    title = item.find(class_='desc-title') # 在列表中的每个元素里,匹配属性class_='title'提取出数据
    material = item.find(class_='desc-material') #在列表中的每个元素里,匹配属性class_='desc-material'提取出数据
    step = item.find(class_='desc-step') #在列表中的每个元素里,匹配属性class_='desc-step'提取出数据
    print(title.text,'\n',material.text,'\n',step.text)#打印Tag中属性的值

XHR

当网页直接把所有的关键信息都放在第1个请求里,用requests和BeautifulSoup就能解决问题。
当需要的信息不在网页源代码里,而且也不是图片,不是媒体文件,自然只会是在XHR里
Headers:标头(请求信息)、Preview:预览、Response:原始信息、Timing:时间
利用requests.get()访问Headers/General/Requests URL链接,把字典下载到本地。然后去一层一层地解析,拿到json格式的信息

json

将response对象转成特殊的列表/字典

import requests
res_music = requests.get('https://c.y.qq.com/soso/fcgi-bin/client_search_cp?ct=24&qqmusic_ver=1298&new_json=1&remoteplace=txt.yqq.song&searchid=65805191174562925&t=0&aggr=1&cr=1&catZhida=1&lossless=0&flag_qc=0&p=1&n=10&w=%E4%BA%94%E6%9C%88%E5%A4%A9&g_tk=5381&loginUin=0&hostUin=0&format=json&inCharset=utf8&outCharset=utf-8&notice=0&platform=yqq.json&needNewCode=0')
json_music = res_music.json()#使用json()方法,将response对象转为列表/字典
print(type(json_music))#打印数据类型,为dict

request headers

user-agent(既用户代理)记录的就是我的电脑系统信息(win10系统)和浏览器(谷歌浏览器)
origin和referer则是记录了这个请求的最初来源是哪个页面。相比之下referer会比origin更长,这意味着referer会携带更多的信息
与封装params非常类似,只需要将origin或referer一并作为字典写入headers就可以

import requests
url = 'https://c.y.qq.com/soso/fcgi-bin/client_search_cp'
headers = {
	'origin':'https://y.qq.com',
	'referer':'https://y.qq.com/n/yqq/song/004Z8Ihr0JIu5s.html',
	'user-agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36',
	}#伪装请求头,防止反爬虫

response headers

存储服务器响应信息,主要学会提取cooike(具有时效性),利用session优化

cookie = login_in.cookies
#提取cookie的方法:调用requests对象(login_in)的cookie属性获得登录的cookie,并赋值给变量cookie。
comment = requests.post(url_comment,headers=headers,data=data_comment,cookies=cookie)
#用requests.post发起发表评论的请求,放入参数:文章网址、headers、评论参数、cookie参数,赋值给comment。
#调用cookie的方法就是在post请求中传入cookies=cookie的参数。
cookie_dict = requests.utils.dict_from_cookiejar(session.cookies)
#把cookie转化成字典。
cookie_str = json.dumps(cookie_dict)
#调用json模块的dumps函数,把cookie从字典再转成字符串。需要导入json库
cookie_txt = open('cookie.txt', 'r')
#以reader读取模式,打开名为cookie.txt的文件。
cookie_dict = json.loads(cookie_txt.read())
#调用json模块的loads函数,把字符串转成字典。
cookie = requests.utils.cookiejar_from_dict(cookie_dict)
#把转成字典的cookie再转成cookie本来的格式。
session.cookies = cookie
#获取cookie:就是调用requests对象(session)的cookie属性。

在这里插入图片描述

cooike与session

cookie在我们日常访问网站的过程中随处可见。例如当需要经常登录一个网站,但是又不想每次都输入账号密码时,可以勾选一个“记住我”的选项。勾选之后,当再打开这个网站就会自动登录,这就是cookie在起作用。
登录参数在form data

import requests#引入requests。

url_login = 'https://xiaoke.kaikeba.com/example/wordpress/wp-login.php'#把请求登录的网址赋值给url。

headers = {'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64)AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.120 Safari/537.36'}
#加请求头,为了避免被反爬虫
data_login = {
'log': 'kaikeba',  #写入账户
'pwd': 'kaikeba',  #写入密码
'wp-submit': '登录',
'redirect_to': 'https://xiaoke.kaikeba.com/example/wordpress/2019/10/17/%e5%bc%80%e8%af%be%e5%90%a7%e6%97%a0%e6%95%8c%e5%a5%bd%e5%90%83%e7%9a%84%e9%a3%9f%e5%a0%82%e4%b8%80%e5%91%a8%e8%8f%9c%e8%b0%b1/',
'testcookie': '1'
}#把有关登录的参数封装成字典,赋值给data。

login_in = requests.post(url_login,headers=headers,data=data_login)
#用requests.post发起请求,放入参数:请求登录的网址、请求头和登录参数,然后赋值给login_in。
cookie = login_in.cookies#提取cookie的方法:调用requests对象(login_in)的cookie属性获得登录的cookie,并赋值给变量cookie。

url_comment = 'https://xiaoke.kaikeba.com/example/wordpress/wp-comments-post.php'#我们想要评论的文章网址。

data_comment = {
'comment': input('请输入你想要发表的评论:'),
'submit': '发表评论',
'comment_post_ID': '35',
'comment_parent': '0'
}#把有关评论的参数封装成字典。

comment = requests.post(url_comment,headers=headers,data=data_comment,cookies=cookie)#用requests.post发起发表评论的请求,放入参数:文章网址、headers、评论参数、cookie参数,赋值给comment。
#调用cookie的方法就是在post请求中传入cookies=cookie的参数。
print(comment.status_code)#打印出comment的状态码,若状态码等于200,则证明我们评论成功。

cookie中存储着session的编码信息,session中又存储了cookie的信息
当浏览器第一次访问购物网页时,服务器会返回set cookie的字段给浏览器,而浏览器会把cookie保存到本地。
等浏览器第二次访问这个购物网页时,就会带着cookie去请求,而因为cookie里带有会话的编码信息,服务器立马就能辨认出这个用户,同时返回和这个用户相关的特定编码的session。

import requests

session = requests.session()
#用requests.session()创建session对象,相当于创建了一个特定的会话,帮我们自动保持了cookie。

url_login = 'https://xiaoke.kaikeba.com/example/wordpress/wp-login.php'

headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.120 Safari/537.36'
}
data_login = {
    'log':input('请输入账号:'), #用input函数填写账号和密码,这样代码更优雅,而不是直接把账号密码填上去。
    'pwd':input('请输入密码:'),
    'wp-submit':'登录',
    'redirect_to': 'https://xiaoke.kaikeba.com/example/wordpress/2019/10/17/%e5%bc%80%e8%af%be%e5%90%a7%e6%97%a0%e6%95%8c%e5%a5%bd%e5%90%83%e7%9a%84%e9%a3%9f%e5%a0%82%e4%b8%80%e5%91%a8%e8%8f%9c%e8%b0%b1/',
    'testcookie':'1'
}
session.post(url_login,headers=headers,data=data_login)
#在创建的session下用post发起登录请求,放入参数:请求登录的网址、请求头和登录参数。

url_comment = 'https://xiaoke.kaikeba.com/example/wordpress/wp-comments-post.php'#把我们想要评论的文章网址赋值给url_comment。

data_comment = {
'comment': input('请输入你想要发表的评论:'),
'submit': '发表评论',
'comment_post_ID': '35',
'comment_parent': '0'
}#把有关评论的参数封装成字典。

comment = session.post(url_comment,headers=headers,data=data_comment)
#在创建的session下用post发起评论请求,放入参数:文章网址,请求头和评论参数,并赋值给comment。

print(comment)

记录cooike和读取cooike代码如下

import requests
import json#引入json为了记录和读取cooike

session = requests.session()

headers = {'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64)AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.120 Safari/537.36'}

def cookie_read(): # cookie读取。
    cookie_txt = open('cookie_kaikeba.txt', 'r')
    cookie_dict = json.loads(cookie_txt.read())#将json转成字典
    cookie = requests.utils.cookiejar_from_dict(cookie_dict)#将字典转成cooikejar
    return (cookie)
def sign_in():
    url_login = 'https://xiaoke.kaikeba.com/example/wordpress/wp-login.php'
    data_login = {'log': input('请输入你的账号'),'pwd': input('请输入你的密码'),'wp-submit': '登录', 'redirect_to': 'https://xiaoke.kaikeba.com/example/wordpress/2019/10/17/%e5%bc%80%e8%af%be%e5%90%a7%e6%97%a0%e6%95%8c%e5%a5%bd%e5%90%83%e7%9a%84%e9%a3%9f%e5%a0%82%e4%b8%80%e5%91%a8%e8%8f%9c%e8%b0%b1/','testcookie': '1'}
    session.post(url_login, headers=headers, data=data_login)
    # cookie存储。
    cookie_dict = requests.utils.dict_from_cookiejar(session.cookies)
    cookie_str = json.dumps(cookie_dict)
    f = open('cookie_kaikeba.txt', 'w')
    f.write(cookie_str)
    f.close()
def write_message(): #发表评论。
    url_comment = 'https://xiaoke.kaikeba.com/example/wordpress/wp-comments-post.php'
    data_comment = {
        'comment': input('请输入你要发表的评论:'),
        'submit': '发表评论',
        'comment_post_ID': '35',
        'comment_parent': '0'
    }
    return (session.post(url_comment, headers=headers, data=data_comment))

try:#判断cooike是否过期
    session.cookies = cookie_read()
except FileNotFoundError:
    sign_in()
    session.cookies = cookie_read()



num = write_message()
if num.status_code == 200:
    print('成功啦!')
else:
    sign_in()
    session.cookies = cookie_read()
    num = write_message()

selenium

需要设置一个引擎,然后实例化浏览器

from selenium import webdriver #从selenium库中调用webdriver模块
driver = webdriver.Chrome() # 设置引擎为Chrome,真实地打开一个Chrome浏览器

selenium所解析提取的,是Elements中的所有数据,而BeautifulSoup所解析的则只是Network中第0个请求的响应。
在这里插入图片描述
WebElement类对象与Tag对象类似
在这里插入图片描述
获取完整的网页源代码

HTML = driver.page_source#字符串,可以用beautifulsoup提取和解析数据

提交表单

teacher = driver.find_element_by_id('teacher') # 找到【请输入你喜欢的老师】下面的输入框位置
teacher.send_keys('开课吧') # 输入文字
assistant = driver.find_element_by_name('assist') # 找到【请输入你喜欢的助教】下面的输入框位置
assistant.send_keys('全都喜欢') # 输入文字

button = driver.find_element_by_tag_name('button') # 找到【提交】按钮
button.click()

静默模式设置

from selenium import  webdriver #从selenium库中调用webdriver模块
from selenium.webdriver.chrome.options import Options # 从options模块中调用Options类
chrome_options = Options() # 实例化Option对象
chrome_options.add_argument('--headless') # 把Chrome浏览器设置为静默模式
driver = webdriver.Chrome(options = chrome_options) # 设置引擎为Chrome,在后台默默运行

在这里插入图片描述

gevent异步与queue队列

from gevent import monkey#从gevent库里导入monkey模块。
monkey.patch_all()#monkey.patch_all()能把程序变成协作式运行,就是可以帮助程序实现异步。
import gevent
import requests
#导入gevent、time、requests。

url_list = [
    "https://www.kaikeba.com/",
    "https://www.csdn.net/",
    "https://www.json.cn/",
    "https://cn.bing.com/",
    "https://www.jianshu.com/",
    "http://www.techweb.com.cn/",
    "https://www.bilibili.com/",
    "https://www.huxiu.com/"
]#把8个网站封装成列表。

def crawler(url):#定义一个crawler()函数。
    r = requests.get(url)#用requests.get()函数爬取网站。
    print(url,r.status_code)#打印网址、状态码。

tasks_list = [ ]#创建空的任务列表。

for url in url_list:#遍历url_list。
    task = gevent.spawn(crawler,url)#用gevent.spawn()函数创建任务,参数为craweler函数名和crawerler函数的参数url
    tasks_list.append(task)#往任务列表添加任务。

gevent.joinall(tasks_list)#执行任务列表里的所有任务,就是让爬虫开始爬取网站。

如果将1000个任务分成5组进行爬取,这5组是异步,但每组内的200任务是同步的
所以借助queue模块

from gevent import monkey
monkey.patch_all()#从gevent库里导入monkey模块
import gevent
import requests
from gevent.queue import Queue#从gevent库里导入queue模块
monkey.patch_all()#monkey.patch_all()能把程序变成协作式运行,就是可以帮助程序实现异步。

url_list = [
    "https://www.kaikeba.com/",
    "https://www.csdn.net/",
    "https://www.json.cn/",
    "https://cn.bing.com/",
    "https://www.jianshu.com/",
    "http://www.techweb.com.cn/",
    "https://www.bilibili.com/",
    "https://www.huxiu.com/"
]

work = Queue()#创建队列对象,并赋值给work

for url in url_list:#遍历url_list
	work.put_nowait(url)#用put_nowait()函数可以把网址都放进队列里

def crawler():
    while not work.empty():#当队列不是空的时候,就执行下面的程序
        url = work.get_nowait()#用get_nowait()函数可以把队列里的网址都取出
        r = requests.get(url)#用requests.get()函数抓取网址
        print(url,work.qsize(),r.status_code)#打印网址、队列长度、抓取请求的状态码

tasks_list  = [ ]#创建空的任务列表

for x in range(2):#相当于创建了2个爬虫
    task = gevent.spawn(crawler)#用gevent.spawn()函数创建执行crawler()函数的任务
    tasks_list.append(task)#往任务列表添加任务。

gevent.joinall(tasks_list)#用gevent.joinall方法,执行任务列表里的所有任务,就是让爬虫开始爬取网站

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

scrapy框架

创建scrapy项目

#cd 到预设文件夹
scrapy startproject test
  1. 定义数据 items.py
import scrapy#导入scrapy
class BookDoubanItem(scrapy.Item):#定义一个类BookDoubanItem,它继承自scrapy.Item
    title = scrapy.Field()#定义书名的数据属性
    publish = scrapy.Field()#定义出版信息的数据属性
    score = scrapy.Field()#定义评分的数据属性
  1. 核心代码 Test.py 在spiders下
import scrapy
import bs4
from ..items import BookDoubanItem

class DoubanSpider(scrapy.Spider):#定义一个爬虫类
    name = 'book_douban'#定义爬虫名字
    allowed_domains = ['book.douban.com']#爬取域名
    start_urls = ['https://book.douban.com/top250?start=0']#起始网页

    def parse(self, response):#Scrapy里默认处理response
 		bs = bs4.BeautifulSoup(response.text, 'html.parser')# 用BeautifulSoup解析response

        datas = bs.find_all('tr', class_="item")# 用find_all提取<tr class="item">元素,这个元素里含有书籍信息
        for data in datas:# 遍历data
            item = BookDoubanItem()# 实例化DoubanItem这个类
            item['title'] = data.find_all('a')[1]['title']# 提取出书名,并把这个数据放回DoubanItem类的title属性里
            item['publish'] = data.find('p', class_='pl').text# 提取出出版信息,并把这个数据放回DoubanItem类的publish里
            item['score'] = data.find('span', class_='rating_nums').text# 提取出评分,并把这个数据放回DoubanItem类的score属性里。
            print(item['title'])# 打印书名
            yield item# yield item是把获得的item传递给引擎    
  1. 存储文件csv settings.py
FEED_URI='%(name)s.csv'#导出文件路径,把CSV文件放到与settings.py文件同级文件夹内
FEED_FORMAT='CSV'#导出数据格式,写CSV就能得到CSV格式
FEED_EXPORT_ENCODING='ansi'#导出文件编码,ansi是一种在windows上的编码格式,你也可以把它变成utf-8用在mac电脑上
  1. 修改设置 settings.py
# Crawl responsibly by identifying yourself (and your website) on the user-agent

USER_AGENT = 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.87 Safari/537.36'

# Obey robots.txt rules

ROBOTSTXT_OBEY = False
  1. 运行
    两种方式,cmd中跳转到scrapy文件件,输入scrapy crawl book_douban(book_douban就是我们爬虫的名字)。
    或者是在最外层的大文件夹里新建一个main.py文件(与scrapy.cfg同级),键入如下代码
from scrapy import cmdline

#导入cmdline模块,可以实现控制终端命令行

cmdline.execute(['scrapy','crawl','book_douban'])

#用execute()方法,输入运行scrapy的命令
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值