第一天 学习requests

用程序去获取网页上的数据

过程:1) 获取网页数据(requests、selenium)、 2)解析数据(正则表达式-re、css选择器-bs4、xpath-lxml)
3) 保存数据(数据库、csv文件、excel文件)
user-agent(身份伪装,将爬虫程序伪装成浏览器)、登录反爬(设置cookie)、字体反爬

1. 获取网页数据

requests.get(网页地址) - 获取网页数据,返回一个响应对象
参数headers: 请求头,需要一个字典,这个字典有两个常见的键值对
1)user-agent:客户端信息,可以设置成浏览器信息,将爬虫程序伪装成一个浏览器
2)cookie:账号登录信息账号登录信息,设置成账号登录成功后cookie值,可以跳过网页登录,获取登录后的数据

headers = {
    'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36'
}
response = requests.get('https://movie.douban.com/top250', headers=headers)
# 2.从响应对象中获取请求结果
# <Response [418]>    418是状态码,状态码为200的时候才表示请求成功
print(response)

# 1)获取响应头
print(response.headers)

# a. 设置网页的编码方式(针对请求对象是网页的时候,如果网页内容打印乱码)
response.encoding = 'utf-8'


# 2)获取响应内容(请求结果)
# a. 响应对象.text    -   获取字符串形式的请求结果(获取网页源代码(请求对象是一个网页地址))
print(response.text)

# b. 响应对象.content  -  获取二进制形式的请求结果(请求对象是图片、视频、音频等)
# print(response.content)

# c. 响应对象.json()   - 获取请求结果做json转换后的结果(请对象是json接口)
# print(response.json())
import requests

# 1. 网页
# https://cd.zu.ke.com/zufang   -  请求对象是网页地址
# headers = {
#     'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36'
# }
# response = requests.get('https://cd.zu.ke.com/zufang', headers=headers)
#
# print(response.text)

# 2. 图片下载
# https://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png  - 请求对象是图片地址
# headers = {
#     'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36'
# }
# url = 'https://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png'
# response = requests.get(url, headers=headers)
# open('files/a.png', 'wb').write(response.content)

# 3.json数据解析
# http://api.tianapi.com/auto/index?key=c9d408fefd8ed4081a9079d0d6165d43&num=10  - json数据接口
# response = requests.get('http://api.tianapi.com/auto/index?key=c9d408fefd8ed4081a9079d0d6165d43&num=10')
# result = response.json()
# for x in result['newslist']:
#     print(x['title'])

正则表达式解析数据 作业

import requests
from re import findall
import csv
import json


# 需求1:获取top250首页数据中所有电影的电影名称(打印电影名)
def get_film_name():
    headers = {
        'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36'
    }
    response = requests.get('https://movie.douban.com/top250', headers=headers)
    result = findall(r'(?s)<img width="100" alt="(.+?)"', response.text)
    print(result)


# 需求2:获取top250首页数据中所有电影的所有数据(包括电影名称、导演、主演、评分、评论数、描述、图片地址),将数据存储到csv文件
def get_one_page(start=0):
    headers = {
        'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36'
    }
    response = requests.get(f'https://movie.douban.com/top250?start={start}&filter=', headers=headers)

    # 解析数据
    result = findall(r'(?s)<li>.+?<img width="100" alt="(.+?)"\s*src="(.+?)".+?<p class="">(.+?)</p>.+?<span class="rating_num" property="v:average">(.+?)</span>.+?<span>(.+?)人评价</span>.+?<span class="inq">(.+?)</span>.+?</li>', response.text)

    data = []
    for x in result:
        line = list(x)
        message = line.pop(2).strip()
        director = findall(r'导演: (.+?)&', message)
        director = director[0] if director else ''

        leading_role = findall(r'主演: (.+?)<br>', message)
        leading_role = leading_role[0] if leading_role else ''

        time = findall(r'\s+(\d{4})&', message)
        time = time[0] if time else ''

        line.extend([director, leading_role, time])
        data.append(line)

    # 写入csv
    writer = csv.writer(open('files/电影.csv', 'a', newline=''))
    if start == 0:
        writer.writerow(['电影名', '封面', '评分', '评论人数', '描述', '导演', '主演', '上映时间'])
    writer.writerows(data)
def get_51job():
    response = requests.get('https://search.51job.com/list/000000,000000,0000,00,9,99,数据分析,2,1.html?lang=c&postchannel=0000&workyear=99&cotype=99&degreefrom=99&jobterm=99&companysize=99&ord_field=0&dibiaoid=0&line=&welfare=')
    # print(response.text)
    json_str = findall(r'window.__SEARCH_RESULT__ = (\{.+?\})</script>', response.text)[0]
    data = json.loads(json_str)
    for job in data['engine_jds']:
        print(job['job_name'])


# 需求3:获取top250所有电影的所有数据(包括电影名称、导演、主演、评分、评论数、描述、图片地址),将数据存储到csv文件
if __name__ == '__main__':
    # for x in range(0, 250, 25):
    #     get_one_page(x)
    get_51job()

网页数据解析

1.beautifulsoup4

beautifulsoup4是基于css选择器来解析网页数据的第三方库。
原理:先通过css选择器选中标签,然后再获取标签内容或者标签属性

2.用法

  1. 准备网页数据(获取网页源代码)
    data = open(‘data.html’).read()

  2. 用bs4解析网页
    导入第三方库(注意:安装的时候装beautifulsoup4, 使用的时候用bs4)
    from bs4 import BeautifulSoup

a.创建BeautifulSoup对象

BeautifulSoup(网页内容, ‘lxml’) - 返回一个BeautifulSoup对象,这个对象指向整个网页
soup = BeautifulSoup(data, ‘lxml’)

b.获取标签

BeautifulSoup对象.select(css选择器) - 返回css选择器选中的所有标签对应的列表(在整个网页中查找)
BeautifulSoup对象.select_one(css选择器) - 返回css选择器选中的所有标签里面的第一个标签(在整个网页中查找)
标签对象.select(css选择器) - 在指定标签中按照css选择器选中标签, 选所有
标签对象.select_one(css选择器) - 在指定标签中按照css选择器选中标签,选一个

result = soup.select('#all-goods .title')
print(result)

result = soup.select_one('#all-goods .title')
print(result)

result = soup.select('p')       # 选中整个网页中的p标签
print(result)

div = soup.select_one('#all-staff')
result = div.select('p')        # 选中id为all-staff的标签里面所有的p标签
print(result)
# c.获取标签内容和标签属性
# 获取标签内容:标签对象.text
all_goods = soup.select('.goods>.title')
for x in all_goods:
    print(x.text)

goods = soup.select_one('.goods>.title')
print(goods.text)

# 获取标签属性:标签对象.attrs[属性名]
all_img = soup.select('.goods>img')
for x in all_img:
    print(x.attrs['src'])

作业练习

import requests
from bs4 import BeautifulSoup
from re import sub

# 1. 获取网页数据
response = requests.get('https://cd.zu.ke.com/zufang')
# print(response.text)

# 2. 解析网页数据
soup = BeautifulSoup(response.text, 'lxml')
all_house = soup.select('.content__list>.content__list--item')
data = []
for house in all_house:
    # 名字
    name = house.select_one('.twoline').text.strip()
    # 价格
    price = house.select_one('.content__list--item-price').text

    # 地址-面积-户型
    p = house.select_one('.content__list--item--des')
    message = sub(r'\s+', '', p.text)
    data.append([name, price, message])

print(data)

import time

time.sleep(1)

课后作业

import requests
from bs4 import BeautifulSoup
from re import sub
import csv
import time
import random

data = []
for x in range(1, 101):
    a = 2 * random.random()
    response = requests.get('https://cd.zu.ke.com/zufang/#contentList')
    time.sleep(a)
    soup = BeautifulSoup(response.text, 'lxml')
    all_house = soup.select(' .content__list>.content__list--item')
    for house in all_house:
        name = house.select_one(' .twoline').text.strip()
        price = house.select_one('.content__list--item-price').text
        location_message = house.select_one(' .content__list--item--des').text
        locations = sub(r'\s+', '', location_message)
        data.append([name, price, locations])
writer = csv.writer(open('files/贝壳租房数据.csv', 'w'))
writer.writerow(['房名', '租金', '位置'])
writer.writerows(data)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值