模板第一次总结--思路

(1)
问题:爬取7天的 天气情况 日期 天气状况温度 风力–> 保存到CSV

分析需求 要干什么事情 通过什么技术来解决
爬取7天的 天气情况 日期 天气状况温度 风力–> 保存到CSV

具体步骤(分析页面)
1.先明确目标url
通过分析我们发现要爬取的数据都在 ul class=“t clearfix” 这个标签当中,然后我们就去网页的源代码中确定了
2.先获取网页的源代码 整个html文件
3.从网页的源代码当中去匹配ul标签的数据
4.从ul标签里面去匹配li标签的数据
5.去解析li标签里面的数据
5.保存数据

import requests
import re
import csv

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

class WeatherSpider:

    # 获取网页源代码
    # 类对象 实例对象 实例方法 类方法
    def getSource(self):
        # 目标url
        url = 'http://www.weather.com.cn/weather/101250101.shtml'
        resp = requests.get(url,headers=headers)
        # print(resp.content.decode('utf-8'))
        return resp.content.decode('utf-8')

    # 解析数据 保存数据
    def parseSource(self):
        content = self.getSource()
        # 匹配ul 正则表达式比较灵活 .*?ul标签前面的数据
        # 匹配并获取的 (
    .*?
) .*?ul标签后面的数据
result = re.match(r'.*?(
    .*?
).*?'
,content,re.S) # print(result.group(1)) # 匹配li ul = result.group(1) lis = re.findall(r'.*?',ul,re.S) lst_all = [] # 保存所有的天气数据 pattern = re.compile(r'.*?

(.*?)

.*?(.*?)

.*?(.*?).*?(.*?).*?'
,re.S) for li in lis: # lst_one = [] # 保存一天的天气数据 r = pattern.match(li) # print(r.group(1),end='') # print(r.group(2),end='') # print(r.group(3),end='') # print(r.group(4),end='') # print() lst_one = [r.group(1),r.group(2),r.group(3),r.group(4)] lst_all.append(lst_one) return lst_all # 保存数据 def saveData(self): content = self.parseSource() with open('weather7day.csv','w',encoding='utf-8',newline='') as file_obj: writer = csv.writer(file_obj) writer.writerow(['日期','天气','温度','风力']) writer.writerows(content) def main(): WeatherSpider().saveData() if __name__ == '__main__': main()

(2)
豆瓣top250电影
问题: 爬取 电影的名字 评分 引言 详情页的url 保存到csv文件当中

具体步骤(分析页面)
1 明确url (是否是静态网页,对比源代码与检查)
2 先像目标url发起请求 获取网页源码
3 可以把网页源码通过 etree.HTML 生成一个element对象
element对象 通过xpath进行导航 电影的名字 评分 引言 详情页的url
4 我们可以把数据先保存到一个字典里面 {title:‘肖申克的救赎’,‘start’:9.7…} ,{title:‘霸王别姬’,‘start’:9.7…} 在把这些字典保存到一个列表当中
5 把列表中的数据存到csv文件当中

import requests
from lxml import etree
import csv

# 目标Url
doubanUrl = 'https://movie.douban.com/top250?start={}&filter='

# 定义一个函数 获取网页源码
def getSource(url):
    headers = {
     
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.128 Safari/537.36'
    }
    response = requests.get(url,headers=headers)
    response.encoding = 'utf-8'
    return response.text

# 解析数据 电影的名字 评分 引言 详情页的url
def getEveryItem(source):
    html_element = etree.HTML(source)
    # class="info" 电影的名字 评分 引言 详情页的url 25
    movieItemList = html_element.xpath('//div[@class="info"]')
    movieList = []
    for eachMoive in movieItemList:
        movieDict = {
     }
        title = eachMoive.xpath('div[@class="hd"]/a/span[@class="title"]/text()') # 标题
        otherTitle = eachMoive.xpath('div[@class="hd"]/a/span[@class="other"]/text()')  # 副标题
        link = eachMoive.xpath('div[@class="hd"]/a/@href')[0] # url
        star = eachMoive.xpath('div[@class="bd"]/div[@class="star"]/span[@class="rating_num"]/text()')[0] # 评分
        quote = eachMoive.xpath('div[@class="bd"]/p[@class="quote"]/span/text()') # 引言(名句)
        # 第一种异常处理
        # 第二种非空判断
        if quote:
            quote = quote[0]
        else:
            quote = ''
        movieDict['title'] = ''.join(title + otherTitle) # 主标题要 + 父标题
        movieDict['url'] = link
        movieDict['star'] = star
        movieDict['quote'] = quote
        print(movieDict)
        movieList.append(movieDict)

    return movieList


# 保存数据 次数 Ip检测  代理Ip(付费)
def writeData(movieList):

    with open('douban.csv','w',encoding='utf-8',newline='') as file_obj:
        writer = csv.DictWriter(file_obj,fieldnames=['title','star','quote','url'])
        writer.writeheader()
        for each in movieList:
            writer.writerow(each)


if __name__ == '__main__':
    movieList = [] 

    for i in range(10):
        pageLink = doubanUrl.format(i * 25)

        source = getSource(pageLink)

        movieList = getEveryItem(source) # 保存的最后一页 movieList = movieList + getEveryItem(source)  a = 1  a += 1

    writeData(movieList)

(3)
问题:爬取中国天气网 所有城市对应的温度把数据保存到csv当中
具体步骤(分析页面)
目标url
http://www.weather.com.cn/textFC/hb.shtml 华北
http://www.weather.com.cn/textFC/db.shtml 东北

1> 我们发现每一个url 对应一个大区。所以我们先搞定一个 在去搞定其他的
2> 1. 先找到整页的 div=conMidtab 标签的数据
2. 接下来去找每一个省或者直辖市所对应的table标签
3. 找table标签里面的tr标签(需要注意 要把前2个tr过滤掉)
4. 去tr标签里面找td标签(第0个是城市 倒数第二个是温度)

import requests
from bs4 import BeautifulSoup
import csv
# 保存到csv文件当中 列表里面 [{城市:xxx,温度:7},{}....]
titles = ('city','temp')

def pares_page(url):
    headers = {
     
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.128 Safari/537.36'
    }
    response = requests.get(url,headers=headers)
    # print(response.content.decode('utf-8'))
    text = response.content.decode('utf-8')

    # 网页解析
    # 1.先找到整页的 div=conMidtab 标签的数据
    # html5lib来解析网页 pip isntall html5lib,补全网页源代码
    soup = BeautifulSoup(text,'html5lib')
    conMidtab = soup.find('div',class_='conMidtab')

    # 2. 接下来去找每一个省会或者直辖市所对应的table标签
    tables = conMidtab.find_all('table')


    # 定义一个列表 保存最终的数据 [{},{}]
    lst = []

    for table in tables:
        # 3. 找table标签里面的tr标签(需要注意 要把前2个tr过滤掉)
        trs = table.find_all('tr')[2:]
        for index,tr in enumerate(trs): # enumerate() 返回的是 下标所以以及对应的值
            tds = tr.find_all('td')
            city_td = tds[0] # 直辖市/省
            if index == 0:
                city_td = tds[1]

            info = {
     }
            '''
            从打印的结果发现了如果我们取0的时候 只有省的第一个城市(省会)是不对的。其它的数据都是正确的。改成1的时候只有省会是对的,其它的就都是错误的。
            我们什么情况下 取第一个数据 tds[1] 省会
            '''
            city = list(city_td.stripped_strings)[0] # 城市,*取字符串的套路*
            temp_td = tds[-2]
            temp = list(temp_td.stripped_strings)[0] # 温度

            info['city'] = city
            info['temp'] = temp
            lst.append(info)
            print('city:',city,'temp:',temp)
        # break # 先打印北京的
    return lst


def writeData(lst):
    with open('wather.csv','w',encoding='utf-8',newline='') as file_obj:
        writer = csv.DictWriter(file_obj,titles)
        writer.writeheader()
        writer.writerows(lst)


def main():
    lst = []
    # 目标url 先去搞定一个区域 在去搞定其它的区域
    url = 'http://www.weather.com.cn/textFC/hb.shtml' # 华北
    url = 'http://www.weather.com.cn/textFC/db.shtml' # 东北
    url = 'http://www.weather.com.cn/textFC/gat.shtml' # 港澳台

    urls = ['http://www.weather.com.cn/textFC/hb.shtml','http://www.weather.com.cn/textFC/db.shtml','http://www.weather.com.cn/textFC/gat.shtml']
    for url in urls:

        lst += pares_page(url)

    writeData(lst)

if __name__ == '__main__':
    main()

(4)
问题:爬取 海贼王吧 爬取桌面壁纸
具体步骤(分析页面)
1.我们发现要爬取的数据是图片,那么就只要找到它(每张图片)的src 就可以了
经过分析发现网页源码当中没有我们想要爬取的数据。然后我们确定它是经过ajax加载的数据
一般情况下 ajax请求都在 XHR这个选项(XMLHttpRequest)
通过network 继续找真实的数据接口
即找到真正的目标url
2.解析数据
可以把(response)数据通过json (利用json.cn)转换成Python的数据类型的字典(preview)。 然后通过key-value形式找到 每张图片的url
也可以通过正则(对(response)数据直接进行解析)
代码:

import requests
import re
import time
'''

https://tieba.baidu.com/photo/g/bw/picture/list?kw=%E6%B5%B7%E8%B4%BC%E7%8E%8B&alt=jview&rn=200&tid=1934517161&pn=1&ps=1&pe=40&info=1&_=1620822548466

https://tieba.baidu.com/photo/g/bw/picture/list?kw=%E6%B5%B7%E8%B4%BC%E7%8E%8B&alt=jview&rn=200&tid=1934517161&pn=1&ps=40&pe=79&wall_type=h&_=1620823519114

https://tieba.baidu.com/photo/g/bw/picture/list?kw=%E6%B5%B7%E8%B4%BC%E7%8E%8B&alt=jview&rn=200&tid=1934517161&pn=1&ps=79&pe=118&wall_type=h&_=1620823534332

ps=1 ps=40 ps=79   pe=40 pe=79 pe=118   规律 39

'''
name = 1
for i in range(1,80,39):


    # 目标url
    # url = 'https://tieba.baidu.com/photo/g/bw/picture/list?kw=%E6%B5%B7%E8%B4%BC%E7%8E%8B&alt=jview&rn=200&tid=1934517161&pn=1&ps=1&pe=40&info=1&_=1620822548466'
    url = 'https://tieba.baidu.com/photo/g/bw/picture/list?kw=%E6%B5%B7%E8%B4%BC%E7%8E%8B&alt=jview&rn=200&tid=1934517161&pn=1&' + '&ps=' + str(i) + '&pe=' + str(39 + i) + '&wall_type=h&_=1620823534332'
    headers = {
     
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.128 Safari/537.36'
    }

    res = requests.get(url,headers=headers)
    # print(res.text)
    # 正则表达式匹配数据
    img_urls = re.findall('"murl":"(.*?)"',res.text)

    for img_url in img_urls:
        img_response = requests.get(img_url)
        # 保存数据
        print('正在下载第%d张图片' % name)
        with open('img/%d.jpg'%name,'wb') as file_obj:
            # time.sleep(0.5)
            file_obj.write(img_response.content)

        name += 1
    time.sleep(1)

(5)
问题:通过selenium登录豆瓣
具体步骤
人怎么做,selenium就怎么做 时刻记住:先定位,再操作

# 登录豆瓣
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import Select
import time

driver = webdriver.Chrome()
driver.get('https://www.douban.com/')
# 切换iframe 灵活变通
'''
NoSuchElementException: Message: no such element: Unable to locate element: {"method":"css selector","selector":".nojs"}
iframe作祟
'''
login_frame = driver.find_element_by_xpath('//*[@id="anony-reg-new"]/div/div[1]/iframe')
driver.switch_to.frame(login_frame)

# 切换登录方式 千万不要忘记click()
# 当属性有空格的时候 account-tab-account on 如何解决呢?
# 1.可以选其中的一部分(通过测试),技巧:选较长的一段 2 xpath来定位
driver.find_element_by_class_name('account-tab-account').click()
time.sleep(2)
# 定位账号和密码 并输入内容
driver.find_element_by_id('username').send_keys('xxxxxx')
time.sleep(1)
driver.find_element_by_id('password').send_keys('xxxxxx')
time.sleep(1)
# 点击登录按钮
driver.find_element_by_class_name('btn').click()

(6)
问题:通过selenium获取cookie(条件:自己不久之前已登过)
具体步骤(分析页面)
获取cookies–>解析数据–>测试

from selenium import webdriver
import requests
import time
import json
# 模拟登录自己的QQ空间

# 携带cookie进行模拟 也就是我们先通过正常的途径进行登录此时此刻就可以获得一个cookie.然后在正常的编写一个 模拟登录的逻辑就可以啦
# 下面的逻辑 1 要通过selenium获取 qq空间的cookie值 2 解析这个cookie值 3 进行测试

#要通过selenium获取 qq空间的cookie值
#把逻辑封装一下 类 方法
driver = webdriver.Chrome()
# 不要删参数  加载第三方的登录方式
driver.get('https://xui.ptlogin2.qq.com/cgi-bin/xlogin?proxy_url=https%3A//qzs.qq.com/qzone/v6/portal/proxy.html&daid=5&&hide_title_bar=1&low_login=0&qlogin_auto_login=1&no_verifyimg=1&link_target=blank&appid=549000912&style=22&target=self&s_url=https%3A%2F%2Fqzs.qzone.qq.com%2Fqzone%2Fv5%2Floginsucc.html%3Fpara%3Dizone&pt_qr_app=%E6%89%8B%E6%9C%BAQQ%E7%A9%BA%E9%97%B4&pt_qr_link=http%3A//z.qzone.com/download.html&self_regurl=https%3A//qzs.qq.com/qzone/v6/reg/index.html&pt_qr_help_link=http%3A//z.qzone.com/download.html&pt_no_auth=0')
time.sleep(1)
button = driver.find_element_by_class_name('face')
button.click()
time.sleep(2)
listCookies = driver.get_cookies() # 是python中的list json.loads()
# # 以下的逻辑可以不写 不实现  目的是保存listCookies,方便后续调用
# jsonCookies = json.dumps(listCookies) # 把python的数据类型转换成json类型的字符串(str)
# print(type(jsonCookies),jsonCookies)
#
# with open('qqzone.json','w') as file_obj:
#     file_obj.write(jsonCookies)


# 解析cookie数据 列表推导式 [] 返回的结果是一个新的列表
cookie = [item['name'] + '=' + item['value'] for item in listCookies]
cookie_str = '; '.join(cookie)
#item for item in cookie
print(cookie_str)


# 测试代码 selenium获取和解析之后的cookie是否可以使用
url = 'https://user.qzone.qq.com/2023203294'
headers = {
     
    'cookie':cookie_str,
    'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36'
}

html = requests.get(url,headers=headers)
time.sleep(2)
with open('qzong.html','w',encoding='utf-8') as file_obj:
    file_obj.write(html.text)
print(html.text)

方法总结:

  • requests 获取URL响应
  • selenium 登陆及操作网页(including:输入框、按钮、下拉框、获取cookie)
  • 三种方法解析html(正则、xpath、bs4)
    实施过的案例种类:爬取天气,保存csv;豆瓣top250电影信息,保存csv;爬取图片,并保存

案例总结:(写代码之前,须对网页检查有充分理解)
1》获取html–>并解析->后保存

  • 明确目标URL(注意对ajax处理)
  • 得html
  • 解析(三种)(先整体,后局部)
  • 保存,注意格式

2》登陆网页,获取cookie
用selenium(requests麻烦且难)

(7)

你可能感兴趣的:(爬虫,网络,selenium,python,正则表达式,xpath,selenium,csv)