程序员的资源宝库

网站首页 > gitee 正文

数据采集与融合实践第三次实践作业

sanyeah 2024-03-29 15:22:05 gitee 7 ℃ 0 评论

作业1

在中国气象网爬取网站的所有图片

  • Gitte文件夹链接:https://gitee.com/prettykuromi/102102137/tree/master/作业3/问题1
  • 首先创建scrapy项目,完成settings.py、run.py等基础文件的编写
  • 分析,要想爬取网站的所有图片,实际上只要获取页面中的a元素的href链接用于跳转,对于单个页面,获取所有img元素的src并下载图片即可。
  • 分析页面,发现img元素的src内是完整的下载网址,因此无需补充完整,myspider.py文件中实现如下代码
# 找到img元素
images = selector.xpath("//img")
for image in images:
    # 获取图片下载地址
    img = image.xpath('@src').extract_first()
    item = WeatherItem()
    item["url"] = img.strip() if img else ""
    yield item

  • 实现翻页,为了控制总页数小于37,每次翻页前增加判断,注意翻页前让程序暂停一会,防止过分频繁的页面请求导致对网址服务器造成骚扰,myspider.py文件中实现如下代码
#部分代码
pages = selector.xpath("//a/@href").extract()
for idx, page in enumerate(pages):
    self.count += 1
    if self.count <= 37:
        url = page
        time.sleep(2)
        yield scrapy.Request(url=url, callback=self.parse)
  • 在pipelines.py文件中,接收传送的url并实现图片下载,首先实现单线程下载。需要限制下载的图片数小于137,同时动态获取图片扩展名
if self.index<=137:
    img_url = item["url"]
    extension = os.path.splitext(img_url)[1]  # 获取扩展名
    # 生成文件名
    imagename = f"D:/images/{self.index}.{extension}"
    self.index += 1
    # 输出下载的url信息
    print(img_url)
    # 单线程下载图片
    urllib.request.urlretrieve(img_url,filename=imagename)
    self.count += 1
else:
    self.opened = False
  • 实现多线程下载图片,部分代码如下
for index, img_url in enumerate(rows):
    thread_name = "thread" + str(index)  # 构建线程名称
    exec("%s = threading.Thread(target=thread, args=(index, img_url))" % thread_name)
    threads.append(eval(thread_name))
    eval(thread_name).start()
  • 最终编写完整代码后,运行run.py文件
    输出的url信息如下

    下载到本地的137张图片,部分如下:

心得体会

  1. 下载图片的时候一定要注意url是否完整,同时动态获取图片的文件扩展名
  2. 使用scrapy编写爬虫项目时要了解scrapy的流程
  3. 做实验的时候不能心急,要细心仔细防止代码出bug

作业2

scrapy爬取东方财富网的数据并存储到数据库中

  • Gittee文件夹链接:https://gitee.com/prettykuromi/102102137/tree/master/作业3/问题2
  • 由于该网站的数据是使用json动态传递的,因此采取抓包的方法获取数据更为简单
  • 分析该json文件,通过简单正则表达式匹配与转换,即可获取字典类型的数据,并获取所需的数据
dammit = UnicodeDammit(response.body, ["utf-8", "gbk"])
data = dammit.unicode_markup
pat = r'\[(.*?)\]'  # 正则表达式
data = re.search(pat, data).group()
dataList = eval(data)  # 现在data是一个数组,其中存放字典
# 分别在字典中提取所需信息
for data in dataList:
    StockId = str(data['f12'])
    Name = data['f14']
    NewPrice = str(data['f2'])
    UpDown = str(data['f3'])
    DownUp = str(data['f4'])
    DealNum = str(data['f5'])
    DealPrice = str(data['f6'])
    Up = str(data['f7'])
  • 实现翻页,分析获取的json文件的url链接,并限制翻页页数
if self.page <= 7:
    self.page += 1
    url = f'https://69.push2.eastmoney.com/api/qt/clist/get?cb=jQuery112404359196896638151_1697701391202&pn={self.page+1}&pz=20&po=1&np=1&ut=bd1d9ddb04089700cf9c27f6f7426281&fltt=2&invt=2&wbp2u=|0|0|0|web&fid=f3&fs=m:1+t:2,m:1+t:23&fields=f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f12,f13,f14,f15,f16,f17,f18,f20,f21,f23,f24,f25,f22,f11,f62,f128,f136,f115,f152&_=1697701391203'
    time.sleep(2)
    yield scrapy.Request(url=url, callback=self.parse)
  • 在pipelines.py文件中,向mysql数据库中插入获取到的数据
if self.opened:
    self.index+1
    self.cursor.execute(
        "insert into Stocks (StockId,Name,NewPrice,UpDown,DownUp,DealNum,DealPrice,Up) values(%s,%s,%s,%s,%s,%s,%s,%s)",
        (item["StockId"], item["Name"], item["NewPrice"], item["UpDown"], item["DownUp"],
            item["DealNum"], item["DealPrice"], item["Up"]))
    self.count += 1
  • 最终运行run.py文件,共获得180条数据,展示mysql数据库中的数据如下:

心得体会

  • 在f12调试抓包时要留意数据所在的json文件,同时分析不同页面间的url的关系,以更好爬取数据
  • 使用正则表达式时要细心,正确获取所需数据
  • 使用mysql时要注意传送的数据类型和数据库中的类型一致

作业3

爬取中国银行网的外汇数据并存储到数据库中

  • Gittee文件夹链接:https://gitee.com/prettykuromi/102102137/tree/master/作业3/问题3
  • 首先f12进行抓包,发现该网页并没有使用ajax进行数据传递,因此采用常规的xpath分析获取所需数据。
    需要注意,有些数据是空值,因此需要做特殊处理
tds = li.xpath("./td")
if tds:
    name = tds[0].xpath('./text()').extract()[0] if tds[0].xpath('./text()').extract() else ""
    nowbuy = tds[1].xpath('./text()').extract()[0] if tds[1].xpath('./text()').extract() else ""
    moneybuy = tds[2].xpath('./text()').extract()[0] if tds[2].xpath('./text()').extract() else ""
    nowseal = tds[3].xpath('./text()').extract()[0] if tds[3].xpath('./text()').extract() else ""
    moneyseal = tds[4].xpath('./text()').extract()[0] if tds[4].xpath('./text()').extract() else ""
    mid = tds[5].xpath('./text()').extract()[0] if tds[5].xpath('./text()').extract() else ""
    date = tds[6].xpath('./text()').extract()[0] if tds[6].xpath('./text()').extract() else ""
    time_ = tds[7].xpath('./text()').extract()[0] if tds[7].xpath('./text()').extract() else ""
  • 同样需要实现翻页功能,分析url间关系,使用如下代码实现翻页且限制爬取页面数
if self.page <= 7:
    self.page += 1
    url=f'https://www.boc.cn/sourcedb/whpj/index_{self.page}.html'
    time.sleep(2)
    yield scrapy.Request(url=url, callback=self.parse)
  • pipelines.py文件中,实现接收传递的数据并进行下载带mysql数据库中
if self.opened:
    self.cursor.execute(
        "insert into bank (name,nowbuy,moneybuy,nowseal,moneyseal,mid,date,time_) values(%s,%s,%s,%s,%s,%s,%s,%s)",
        (item["name"], item["nowbuy"], item["moneybuy"], item["nowseal"], item["moneyseal"],
            item["mid"], item["date"], item["time_"]))
    self.count += 1
  • 最终运行run.py文件,下载共243条数据,展示部分如下:

心得体会

  1. 获取页面数据时要注意观察、判断页面元素是否为空
  2. 存放数据库时注意检查数据是否有多余无用符号,比如多余的引号或括号,如有需要删除
  3. 存储数据到数据库中时要注意数据类型一致

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表