数据采集第三次大作业

发布时间:2022-07-01 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了数据采集第三次大作业脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。

第三次大作业

作业1

1.1实验题目

  • 要求:指定一个网站,爬取这个网站中的所有的所有图片,例如中国气象网(http://www.weather.COM.cn)。分别使用单线程和多线程的方式爬取。(限定爬取图片数量为学号后3位)

  • 输出信息:

    将下载的Url信息在控制台输出,并将下载的图片存储在images子文件夹中,并给出截图。

1.2单线程编写思路

1.2.1获取天气网主页的所有链接

​ 因为想要实现翻页,所以开始考虑从不同地区的天气页面来进行翻页,但是得到每个地区的编号进行翻页十分麻烦,同时存在许多相同图片。

​ 所以最后考虑从主页获得其他页面链接,从中得到图片

start_url = "http://www.weather.com.cn/"
data = getHTMLText(start_url)
html=etree.HTML(data)
#找到主页下所有a中的href属性
urlli = html.xpath("//a/@href")

​ 因为得到的urlli中存在不是其他页面的链接,比如:

数据采集第三次大作业

​ 所以,使用以下代码进行筛选:

urls=[]
for url in urlli:
    if(url[0:7]=="http://"):
        urls.apPEnd(url)

1.2.2从链接中得到图片链接

​ 提取每个链接中的图片链接,然后除去相同的链接,每次出现一个新的图片链接就调用下载图片的方法对图片进行下载。

images = soup.select("img")
    for image in images:
        try:
            src = image["src"]
            url = urllib.request.urljoin(start_url,src)
            if url not in urls:
                count += 1
                if count>15:
                    break
                urls.append(url)
                PRint(url)
                download(url,count)
        except Exception as err:
            print(err)

1.2.3图片下载

file_name = url.splIT('/')[-1]
rep = requests.get(url)
with open("images\"+ file_name, 'wb') as f:
     f.write(rep.content)
f.close()
 print("downloaded " +  file_name )

1.2.4结果

控制台输出图片链接以及下载成功的提醒。

数据采集第三次大作业

本地文件夹images下的结果。

数据采集第三次大作业

1.3多线程编写思路

1.3.1多线程与单线程区别

​ 主要在于要存在子进程,所以使用threads = []来存储进程,以及使用部分,代码如下:

T = threading.Thread(target=download, args=(url,))
T.setDaemon(False)
T.start()
threads.append(T)

​ 其余部分与单线程一致。

1.3.2 结果

控制台输出图片链接以及下载成功的提醒。

数据采集第三次大作业

本地文件夹images下的结果。

数据采集第三次大作业

1.4完整代码

https://gitee.com/q_kj/crawl_project/tree/master/third

1.5小结

​ 这题开始困扰我的主要在于如何进行翻页,如果对地区天气界面进行翻页太过于复杂,所以最后从主界面中提取其他页面链接进行爬取。其他部分参考课上的代码进行修改便可。

作业2

2.1实验题目

  • 要求:使用scrapy框架复现作业①。

  • 输出信息:

    同作业1

2.2思路

2.2.1 items.py

class WeatherItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    imag = scrapy.Field()

​ imag用于存储图片的链接。

2.2.2MySpider.py

parse函数主要用于获得主页面所有其他页面的链接。

urls=[]
#先找到主页上所有的a标签下的herf属性
urllib = response.xpath("//a/@href").extract()
    for url in urllib:
#因为有些herf属性的结果不是链接,所以进行筛选,结果存入urls
        if (url[0:7] == "http://"):
            if url not in urls:
                urls.append(url)
        #对每个链接调用图片爬取的函数
    for url in urls:
        if self.count<135:
            yield scrapy.Request(url=url,callback=self.imageSpider)

imageSpider函数主要用于获得页面所有图片的链接。

imgurl=[]
        #提取每个img标签中的src属性中的图片链接
img_url = reponse.xpath("//img//@src").extract()
        #if self.count>=135:
            #return
for url in img_url:
        #不确定每个都是否是链接,就进行了筛选
    if (url[0:7] == "http://"):
            #排除重复的标签
         if url not in imgurl:
            self.count += 1
                #如果图片大于135,就不行添加
            f self.count < 135:
                imgurl.append(url)
for url in imgurl:
    item = WeatherItem()
    item["imag"] = url
    yield item

2.2.3 pipelines.py

​ 开启spideropen_spider

    def open_spider(self,spider):
        print("opened")
        self.opened=True
        self.count=0

​ 关闭spiderclose_spider

    def close_spider(self,spider):
        if self.opened:
            self.opened=False
            print("closed")
            print("总共爬取",self.count,"张图片")

​ 上诉部分是对老师所给ppt中的代码进行改写后的。

process_item实现图片的下载:

self.count = self.count + 1
img=item["imag"]
print(img)
#if self.count>135:
    #self.close_spider()
if self.opened:
    try:
         #将图片下载到本地文件夹中
         rep = requests.get(img)
         file_name = img.split('/')[-1]
         with open("images\" + file_name, 'wb') as f:
             f.write(rep.content)
         f.close()
         print("downloaded " + file_name)

2.2.4结果

​ 控制台信息:

数据采集第三次大作业

​ images文件夹下结果:

数据采集第三次大作业

2.3完整代码

https://gitee.com/q_kj/crawl_project/tree/master/weather

2.4小结

​ 第二题和第一题十分相似,第二题主要在于scrapy框架中的各个文件的编写。

作业3

3.1实验题目

  • 要求:爬取豆瓣电影数据使用scrapy和xpath,并将内容存储到数据库,同时将图片存储在

    imgs路径下。

  • 候选网站: https://movie.douban.com/top250

  • 输出信息:

    序号 影名称 导演 演员 简介 电影评分 电影封面
    1 肖申克的救赎 弗兰克·德拉邦特 蒂姆·罗宾斯 希望让人自由 9.7 ./imgs/xsk.jpg
    2....

3.2思路

3.2.1 item.py

class DoubanItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    rank = scrapy.Field()
    movie_name = scrapy.Field()
    director = scrapy.Field()
    actors = scrapy.Field()
    brief_introduction = scrapy.Field()
    grade = scrapy.Field()
    imag = scrapy.Field()

3.2.2 spider.py

​ 通过xpath提取各个部分的内容:

rank = response.xpath("//div[@class='pic']/em/text()").extract() #排名
name = response.xpath("//div[@class='hd']/a/span[1]/text()").extract() #电影名字
dir_acts = response.xpath("//div[@class='bd']/p[1]/text()").extract() #因为导演和演员信息混在一起,所以需要再次提取
brief_intro = response.xpath("//div[@class='bd']/p[2]/span/text()").extract() #简介
grade = response.xpath("//div[@class='bd']/div[@class='star']/span[@class='rating_num']/text()").extract() #评分
img = response.xpath("//div[@class='pic']/a/img/@src").extract() #电影封面图片链接

​ 然后问题在于通过上面得到的导演和主演的信息混在一起,同时还有其他信息,如下图:

数据采集第三次大作业

​ 所以需要再次对其进行提取:

dname = [] #用来存导演名
aname = [] #用来存主演名
count = 0 #用于后面区分dir_acts中的奇偶
#发现每一个电影的dir_act都窜在两个部分,第一部分是导演和主演,第二部分是地区和日期等
#所以考虑提取dir_acts中的偶数部分,即导演和主演
for dir_act in dir_acts:
     count += 1
     if (count % 2 != 0):
      	#导演和主演之间存在"xa0xa0xa0",所以以此分割成两部分
        dir_act = dir_act.strip().split('xa0xa0xa0')
        #提取出的第一部分去除”导演:“,存入dname中
        dname.append(dir_act[0].split('导演:')[1])
        # 提取出的第二部分去除”主演:“,存入aname中
        aname.append(dir_act[1].split('主演:')[1])
     elif (count % 2 == 0):
        continue

​ 然后将最终结果存入item中:

item = DoubanItem()
item["rank"] = int(rank[i])
item["movie_name"] = name[i]
item["director"] = dname[i]
item["actors"] = aname[i]
item["brief_introduction"] = brief_intro[i]
item["grade"]=grade[i]
item["imag"] = img[i]
yield item

​ 最后在于翻页:

#实现翻页,https://movie.douban.com/top250?start=(?)&amp;filter=,?中正好是25的倍数,以此实现翻页
url_f="https://movie.douban.com/top250"
for i in range(1,10):
    url=url_f+"?start="+str(i*25)+"&filter="
    #得到下一页的url,回调parse,继续上面的操作
    yield scrapy.Request(url=url,callback=self.parse)

3.2.3pipelines.py

open_spider:打开spider,同时创建数据库和表。

    def open_spider(self,spider):
        print("opened")
        try:
            #与数据库进行连接,创建douban数据库
            self.con = SQLite3.connect("douban.db")
            self.cursor = self.con.cursor()
            #创建表
            self.cursor.execute("create table douban(排名 int(4),电影名 vArchar(25),导演 VARchar(30),主演 varchar(70),简介 varchar(70),评分 varchar(8),封面 varchar(80))")
            self.opened = True
        except Exception as err:
            print(err)
            self.opened=False

close_spider:用于关闭spider。

def close_spider(self,spider):
    if self.opened:
    self.con.commit()
    self.con.close()
    self.opened=False

process_item:用于插入数据和下载图片。

 #向表中插入item中的数据
 self.cursor.execute("insert into douban(排名,电影名,导演,主演,简介,评分,封面)values(?,?,?,?,?,?,?)",(item['rank'],item['movie_name'],item['director'],item['actors'],item['brief_introduction'],item['grade'],item['imag']))
#将电影封面存入本地文件夹中
rep = requests.get(img)
print(img)
#将封面名设为电影名
file_name = item['movie_name']
with open("images\" + file_name+".jpg", 'wb') as f:
    f.write(rep.content)
f.close()
print("downloaded " + file_name)

3.2.4结果

控制台信息:

数据采集第三次大作业

数据库结果:

数据采集第三次大作业

images本地文件夹照片结果:

数据采集第三次大作业

3.3完整代码

https://gitee.com/q_kj/crawl_project/tree/master/douban

3.4小结

​ 因为之前代码一直爬取不成功,所以多次爬取,最后提示检测到有异常请求从你的 IP 发出,然后登陆豆瓣,虽然没有这个提醒,但又显示了Crawled (403) <GET https://movie.douban.com/top250> (referer: None),根据https://www.cnblogs.com/guanguan-com/p/13540188.html这个链接中的方法成功解决。所以在爬虫时一定要注意:先爬取部分页面内容,正确性测试,没有问题了,联网爬取 爬取要设时间等待,限制速度。

脚本宝典总结

以上是脚本宝典为你收集整理的数据采集第三次大作业全部内容,希望文章能够帮你解决数据采集第三次大作业所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。