数据采集第一次作业

作业一

打印2020年高校排名信息

import requests
from bs4 import BeautifulSoup
from prettytable import PrettyTable


def getHTML(url):  # 相当于是一个通用的的格式函数将目标的网址化为可以作为soup寻找的文本
    try:  # 用来后续debug和程序可读性
        headers = {"User-Agent": "Mozilla/5.0(Windows;U;Windows NT 6.0 x64;en-US;"
                                 "rv:1.9pre)Gecko/200872421Minefield/3.0.2pre"}
        r = requests.get(url, timeout=30, headers=headers)#更换头部可以多次爬取
        r.encoding = r.apparent_encoding#将网页的encoding和爬虫所得到的text同一个编码
        return r.text
    except:
        return ''


def searchinfo(r):  # 将soup可以化成指定需要的soup
    try:
        soup = BeautifulSoup(r, "html.parser")
        return soup
    except:
        return ''


def this_main():  # 单独任务的特殊操作的函数
    print("排名", "名称", "省市", "类型", "总分", "水平", chr(12288)) # 采用中文字符的空格填充chr(12288)
    url = "http://www.shanghairanking.cn/rankings/bcur/2020"  # 这次任务指定的网址
    r = getHTML(url)  # 得到文本
    soup = searchinfo(r)  # 得到soup
    lis = soup.select("a[href$='university']")
    # 由于后面的tr多个不易区分所以想采用next_sibling和parent 但是没有采用find函数而是选择select就找到具有特殊标记的大学名称
    for li in lis:
        try:  # 还是同样的目的
            # 后面的各个参数的传递
            name_in = li.parent
            rank = name_in.previous_sibling
            name = li
            addr = rank.next_sibling
            addr = addr.next_sibling
            type = addr.next_sibling
            fs = type.next_sibling
            cc = fs.next_sibling
            # strip()是用来解决
的问题 但是后面的格式还是会有不一样所以就需要多一个	
            #在prettytable不需要这个问题
            print(rank.text.strip(), name.text.strip(), addr.text.strip(), type.text.strip(), fs.text.strip(), cc.text.strip(),chr(12288))
        except Exception as err:
            print(err)
this_main()  # 调用主函数可以看到结果
![](https://img2020.cnblogs.com/blog/2145459/202009/2145459-20200928182800720-333665573.png)

心得体会

主要是看书上面的代码和结合网络上的资源
第一次尝试去做肯定难度大了一点,最主要的还是将书本上的代码化为自己需要的样子
然后在这次重新提交作业的时候又重新在写了一遍修改了很多也发现爬虫需要多一些实践

作业二

爬取电商的价格

import requests
from bs4 import BeautifulSoup
import bs4

def getHTML(url):  #相当于是一个通用的的格式函数将目标的网址化为可以作为soup寻找的文本
    try:  #用来后续debug和程序可读性
        headers = {"User-Agent": "Mozilla/5.0(Windows;U;Windows NT 6.0 x64;en-US;"
                                 "rv:1.9pre)Gecko/200872421Minefield/3.0.2pre"}
        r = requests.get(url,timeout = 30,headers=headers)
        r.encoding = r.apparent_encoding
        return r.text
    except:
        return ''
    
def searchinfo(r):   #将soup可以化成指定需要的soup
    try:
        soup = BeautifulSoup(r,"html.parser")
        return soup
    except:
        return ''

def this_main():  #单独任务的特殊操作的函数
    print("序号	","商品名称	", "价格	")  #首先将表格的格式表示出来
    url ="http://search.dangdang.com/?key=%CD%BC%CA%E9&act=input&show=big&show_shop=0#J_tab"  #这次任务指定的网址
    r = getHTML(url)  #得到文本
    soup = searchinfo(r)  #得到soup
    coun=0
    lis = soup.select("ul[class='bigimg cloth_shoplist'] li")
    #由于后面的tr多个不易区分所以想采用next_sibling和parent 但是没有采用find函数而是选择select就找到具有特殊标记的大学名称
    for li in lis:
        try:  #还是同样的目的
            #后面的各个参数的传递
            goods_name = li.select('li > a')
            for name in goods_name:
                gname = name["title"]
            # 获得某属性下的值
            price = li.select('p[class="price"] span[class="price_n"]')[0].text
            coun = coun + 1
            print(coun, gname, price)
        except Exception as err:
            print(err)
this_main() #调用主函数可以看到结果

心得体会

一开始是想做苏宁易购的网站但是总是调试不出价格的数据,在本来显示价格的上面却显示 而且有的产品有的在页面上有价格参数有的没有
后来又重新选择当当网
有些不足,但是不知道怎么在原网页上调出价格数据,
这次完成作业的时候又重新写了一遍和原来的不是完全一样
程序的可读性提高很多
函数封装起来,嘻嘻(看起来会规范一些)

作业三

爬取图片

from bs4 import BeautifulSoup
from bs4 import UnicodeDammit
import urllib.request
import re
def imageSpider(start_url):#图片爬取
    try:
        urls = [] #最终所要得到爬取图片的网址一开始会置为空
        req = urllib.request.Request(start_url, headers=headers) #引入全局变量headers改换头部信息实现多次爬取
        data = urllib.request.urlopen(req) #目标网址打开
        data = data.read() #对网站内容进行读操作
        dammit = UnicodeDammit(data, ["utf-8", "gbk"])#用utf-8和gbk来猜测文本编码,从而设置函数最终信息编码标准
        data = dammit.unicode_markup #将内容可转化为text
        soup = BeautifulSoup(data, "lxml") #用lxml来解析
        images = soup.select("img")#选取我们的目标(图片)的tag
        for image in images:#images是存储所有的图片,而image是存取单个图片(可替换)
            src = image["src"]#src存储的是图片的名称
            url = urllib.request.urljoin(start_url, src)#urljoin构建绝对路径
            if url not in urls:#将每一次获取得到的新的单个网址存入urls里面 避免重复
                urls.append(url) #不在,就添加.append
                download(url) #随便下载
                print(url)#打印已经下载的图片
    except Exception as er:
        print(er)


def download(url):#具体的下载过程
    global count #全局变量,设置这个完全是因为想名称给解决哈哈!
    try:
        count = count + 1#我是选择一开始就加一
        if (url[len(url) - 4] == "."):#判断是否为目标文件(图片)
            ext = url[len(url) - 4:]#获取图片的格式jdp还是png
        else:
            ext = ""
        req = urllib.request.Request(url, headers=headers)#可以更有效的多次爬虫
        data = urllib.request.urlopen(req, timeout=100)#防止超时,和第一个函数比有相同的部分,这个就不太好重复工作
        data = data.read()#进行图片的数据读
        fobj = open("images\" + str(count) + ext, "wb")#默认是在编译器存储在同一个文档中,命名形式用count的具体指哈哈,根据读取的格式来结尾,允许读写图片
        fobj.write(data)#写数据
        fobj.close()#最后要关闭这个进程
    except Exception as e:
        print("3e")
start_url = "http://jwch.fzu.edu.cn/"#我爬取的是教务处,其他网站也可以直接更换这条信息即可
headers = {
    "User-Agent": "Mozilla/5.0(Windows;U;Windows NT 6.0 x64;en-US;rv:1.9pre)Gecko/2008072421 Minefield/3.0.2pre"}
count = 0
imageSpider(start_url)


基本上就是在书上的代码修改而得,然后想着要自己写来着但是ddl快到了就没办法,
就基本上将每一行代码给注释一遍,在注释的时候就感觉到这段代码可以再进行细分,然后先提交之后会再补充的

补充作业三

from bs4 import BeautifulSoup
from bs4 import UnicodeDammit
import urllib.request

def goal_images(goal_url):#从目标的url中得到所有图片的urls的集合
    try:
        image_urls=[]#先初始化最终的图片结果
        req = urllib.request.Request(goal_url, headers=headers)  # 引入全局变量headers改换头部信息实现多次爬取
        data = urllib.request.urlopen(req)  # 目标网址打开
        data = data.read()  # 对网站内容进行读操作
        dammit = UnicodeDammit(data, ["utf-8", "gbk"])  # 用utf-8和gbk来猜测文本编码,从而设置函数最终信息编码标准
        data = dammit.unicode_markup  # 将内容可转化为text
        soup = BeautifulSoup(data, "lxml")  # 用lxml来解析
        images = soup.select("img")  # 选取我们的目标(图片)的tag
        try:
            for image in images:
                image_urls=get_image_in_url(goal_url,image,image_urls)#更新图片地址的集合
        except Exception as e:
            print(e)
    except Exception as err:
        print(err)
    return image_urls

def get_image_in_url(goal_or_url,target_image,new_image_urls):#网页的地址,图片所在地址,最终获得图片地址集合
    src = target_image["src"]  # src存储的是图片的名称
    this_url = urllib.request.urljoin(goal_or_url, src)  # urljoin构建绝对路径
    if this_url not in new_image_urls:  # 将每一次获取得到的新的单个网址存入urls里面 避免重复
        new_image_urls.append(this_url)  # 不在,就添加.append
    return new_image_urls

def download_all(image_urls):#下载所有的图片集合
    for url in image_urls:
        enc=judge_url(url)
        download(url,enc)
        print(url)
def download(url,ext):
    global count  # 全局变量,设置这个完全是因为想名称给解决哈哈!
    req = urllib.request.Request(url, headers=headers)  # 可以更有效的多次爬虫
    data = urllib.request.urlopen(req, timeout=100)  # 防止超时,和第一个函数比有相同的部分,这个就不太好重复工作
    data = data.read()  # 进行图片的数据读
    fobj = open("images\" + str(count) + ext, "wb")  # 默认是在编译器存储在同一个文档中,命名形式用count的具体指哈哈,根据读取的格式来结尾,允许读写图片
    fobj.write(data)  # 写数据
    fobj.close()  # 最后要关闭这个进程
    count=count+1
def judge_url(pic_url):
    if (pic_url[len(pic_url) - 4] == "."):  # 判断是否为目标文件(图片)
        ext = pic_url[len(pic_url) - 4:]  # 获取图片的格式jdp还是png
    else:
        ext = ""
    return ext
headers = {
    "User-Agent": "Mozilla/5.0(Windows;U;Windows NT 6.0 x64;en-US;rv:1.9pre)Gecko/2008072421 Minefield/3.0.2pre"}
count = 1
gurl="http://xcb.fzu.edu.cn/html/"
imageurls=goal_images(gurl)
download_all(imageurls)


多加练习还是会有进步的!修改于2020年9月28日21:00

原文地址:https://www.cnblogs.com/021800626-wyj/p/13732480.html