第一次作业——结合三次小作业

作业一

(1)UniversitiesRanking实验

代码:

 1 # wanglu031804127UniversitiesRanking.py
 2 
 3 import requests
 4 from bs4 import BeautifulSoup
 5 
 6 
 7 def getHtmlText(url):
 8     try:
 9         r = requests.get(url, timeout=30)
10         r.raise_for_status()  # 如果状态不是200,则引发HTTPError异常
11         r.encoding = r.apparent_encoding
12         return r.text
13     except:
14         print('响应失败')
15         return ""
16 
17 
18 def printUnivList(html):
19     tqlt = "{0:^10}	{1:{5}^10}	{2:^10}	{3:^10}	{4:^10}"
20     soup = BeautifulSoup(html, 'html.parser')
21     print(tqlt.format("排名", "学校", "省市", "类型", "总分", chr(12288)))  # 采用中文字符的空格填充chr(12288)
22     for tr in soup.find('tbody').children:
23         tds = tr.find_all('td')  # tds为tr标签的列表
24         #  strip()方法用于去除字符串首尾的空白字符
25         print(tqlt.format(tds[0].text.strip(), tds[1].text.strip(), tds[2].text.strip(), tds[3].text.strip(),
26                           tds[4].text.strip(), chr(12288)))
27 
28 
29 uinfo = []
30 url = 'http://www.shanghairanking.cn/rankings/bcur/2020.html'
31 html = getHtmlText(url)
32 printUnivList(html)

 结果图片:

 (2)心得体会

   本次实验我动手实践爬取了大学排名。实验的第一步就是需要爬取网页的内容,用到了Requests库。这个爬取框架是我从网上搜索得来的,通过自己的查询和学习,理解了每一步的作用,比如r.status_code是HTTP请求的返回状态,200表示连接成功;r.encoding是从HTTP header中猜测的响应编码方式,而r.apparent_encoding是从内容中分析出的响应编码方式,因此,将r.apparent_encoding获得的内容赋给r.encoding可以正常看到网页中的内容。之后在编写输出函数的最后一步,输出内容的时候,我遇到了困难。我最开始是用tds[].string的方法输出的,但是最后结果总是报错,提示我有部分内容为NoneType,我在网上搜索了一下,发现一个Tag类型的对象返回一个NavigableString类型的对象,另一方面,.text获取所有的子字符串,并使用给定的分隔符返回连接. .text的返回类型是unicode对象.,因此改成用text.strip()方法输出,显示结果就正常了,这也让我意识到了细心的重要性,考虑问题要全面。

作业二

(1)GoodsPrice实验

代码:

 1 # wanglu031804127 GoodsPrice.py
 2 
 3 import requests
 4 import re
 5 from bs4 import BeautifulSoup
 6 
 7 
 8 def getHTMLText(url):
 9     try:
10         kv = {'user-agent': 'Mozilla/5.0'}
11         r = requests.get(url, headers=kv)  # 加上头部,伪装成浏览器访问,以防爬虫被限制
12         r.raise_for_status()
13         r.encoding = r.apparent_encoding
14         return r.text
15     except:
16         return ""
17 
18 
19 def parsePage(html):
20     try:
21         soup = BeautifulSoup(html, "html.parser")
22         bag = soup.select("div[class='p-name p-name-type-2'] em")  # 爬取商品名信息
23         price = soup.select("div[class='p-price'] i")  # 爬取商品价格信息
24         for i in range(len(bag)):
25             GoodsName.append(bag[i].text.replace("
", "").replace(" ", "").replace("	", ""))  # 去掉空白符
26             GoodsPrice.append(price[i].text.replace(" ", ""))
27     except:
28         print("")
29 
30 
31 def printGoodsList(GoodsName, GoodsPrice):
32     tplt = "{:4}	{:16}	{:8}"  # 规范输出格式
33     print(tplt.format("序号", "商品名", "价格"))
34     for i in range(len(GoodsName)):
35         print(tplt.format(i, GoodsName[i], GoodsPrice[i]))
36 
37 
38 GoodsName = []
39 GoodsPrice = []
40 cate = '书包'  # 指定商品种类
41 depth = 2  # 爬取前两页的商品信息
42 url = 'https://search.jd.com/Search?keyword=' + cate  # 指定商品种类网址
43 # 爬取前两页
44 for i in range(depth):
45     try:
46         url = url + '&page=' + str(1 + i * 2)  # 指定页面
47         html = getHTMLText(url)
48         parsePage(html)
49     except:
50         continue
51 printGoodsList(GoodsName, GoodsPrice

 结果图片:

(2)心得体会

    这次实验和上次实验内容差不多,都是爬取网页内容并输出。但是需要注意的问题有两个。一个是因为京东网站具有反爬虫的机制,所以用上次实验的网页爬取框架可能造成爬虫失败,因此在这次的网页爬取函数中,我自己定义了并添加了一个头部信息,将自己的个人电脑伪装成浏览器去爬取信息,就能成功了;第二个就是商品关键词和爬取页数的问题。老师要求我们爬取两页关于书包的商品和价格信息,因此网页的url是会改变的,我观察了一下在搜索书包关键词下,不同页面url的改变,第一页:https://search.jd.com/Search?keyword=%E4%B9%A6%E5%8C%85&qrst=1&wq=%E4%B9%A6%E5%8C%85&stock=1&page=1&s=1&click=0;第二页:https://search.jd.com/Search?keyword=%E4%B9%A6%E5%8C%85&qrst=1&wq=%E4%B9%A6%E5%8C%85&stock=1&page=3&s=51&click=0,可以看出页码不同体现在page上,因此使用一个for循环就能实现对前两页信息的爬取。

作业三

(1)JPGFileDownload实验

代码:

 1 #  031804127王璐JPGFileDownload.py
 2 
 3 from wsgiref import headers
 4 from bs4 import BeautifulSoup
 5 from bs4 import UnicodeDammit
 6 import urllib.request
 7 
 8 
 9 def imageSpider(start_url):
10     try:
11         urls = []
12         req = urllib.request.Request(start_url, headers=headers)
13         data = urllib.request.urlopen(req)
14         data = data.read()
15         dammit = UnicodeDammit(data, ["utf-8", "gbk"])
16         data = dammit.unicode_markup
17         soup = BeautifulSoup(data, 'lxml')
18         images = soup.select("img")  # 爬取所有图片
19         for image in images:
20             try:
21                 # 获取图片的url
22                 src = image["src"]
23                 url = urllib.request.urljoin(start_url, src)
24                 if url not in urls:
25                     urls.append(url)  # 没有被爬取过的图片就添加
26                     print(url)
27                     download(url)  # 下载图片
28             except Exception as err:
29                 print(err)
30     except Exception as err:
31         print(err)
32 
33 
34 def download(url):
35     global count  # 声明全局变量count
36     try:
37         count = count + 1
38         if (url[len(url) - 4] == "."):  # 图片格式后缀为三位,格式后缀前面的字符为"."
39             ext = url[len(url) - 4:]  # 获取图片格式
40         else:
41             ext = ""
42         # 获取图片文件
43         req = urllib.request.Request(url, headers=headers)
44         data = urllib.request.urlopen(req, timeout=100)
45         data = data.read()
46         # 存储图片到指定位置并命名
47         fobj = open("D:\images\" + str(count) + ext, "wb")  # 以二进制形式打开文件
48         fobj.write(data)
49         fobj.close()
50         print("downloaded" + str(count) + ext)
51     except Exception as err:
52         print(err)
53 
54 
55 start_url = "http://jwch.fzu.edu.cn/"
56 headers = {"User-Agent": "Mozilla/5.0(Windows;U;Windows NT 6.0 x64;en-US;rv:1.9pre)Gecko/2008072421 Minefield/3.0.2pre"}
57 count = 0  # 用于记录爬取图片的个数
58 imageSpider(start_url)

结果图片:

(2)实验心得

  这次实验我是直接参考了书本3.5节,实践项目爬取网站图像文件的代码。由于还没有学习多线程,所以我参考的是单线程爬取图像的程序。下面就来总结一下在本次实验学到了哪些东西:首先就是对图片url的获取,由于教务处网站图片的HTML都是<img src="/Tp/PC/skin1/jwch/images/zhou.png" alt="">的格式,因此要获取图片的url,就要用教务处网站的网址加上“src=”后面的url内容,这就要使用urljoin()方法,将两段网址连接起来,得到图片的url;然后就是图片文件写入的问题,由于图片是以二进制形式存储的,因此要用‘wb’打开文件并写入,才能正确存储图片;最后一点,单线程程序会因为网站某个图像下载过程缓慢而效率低下,因此效率远远没有多线程高,所以在学习掌握了多线程爬取之后,我会改进我的代码,使之更高效。

原文地址:https://www.cnblogs.com/wlululu/p/13731780.html