点击查看【bilibili】
本实例涉及的技术:Requests & BeautifulSoup

内容概要:

1 功能需求
2 目标网站的 robots协议
3 目标网站分析
4 程度结构的设计
5 代码实现
6 本实例全代码

1 功能需求

  1. 获取新闻页面的信息,提取其中的时间、标题、网址信息打印输出信息

2 目标网站的 robots协议

  1. 在网站的根目录下查看网站的 robots协议<br /> 浏览器地址栏中输入:[https://www.phei.com.cn/robots.txt](https://www.phei.com.cn/robots.txt)<br /> 结果如下图所示,网站没有robots.txt,对网络爬虫没有限制 <br />![](https://cdn.nlark.com/yuque/0/2021/webp/22731262/1640668944140-cf1f8af6-0ce2-427a-a726-bee67b3b15f3.webp#clientId=ubb2a537a-4816-4&crop=0&crop=0&crop=1&crop=1&from=paste&id=u0233d313&margin=%5Bobject%20Object%5D&originHeight=283&originWidth=480&originalType=url&ratio=1&rotation=0&showTitle=false&status=done&style=none&taskId=ubc5cad22-778d-45ba-831f-ca990abdb80&title=)<br />本实例仅在技术的学习和探讨<br />网站虽然没有限制,但也请不要无限制爬取。

3 目标网站分析

获取电子工业出版社新闻 - 图1
查看网页源代码:右键>查看网页源代码,可以看到相关信息都保存在html页面中。
获取电子工业出版社新闻 - 图2
新闻网页的信息
获取电子工业出版社新闻 - 图3
新闻网页的跳转方式

4 程度结构的设计

技术路线:Requests-BeautifulSoup
步骤一:Requests 自动网络url请求提交,循环获得html页面
步骤二:BeautifulSoup解析每个HTML页面,提取目标信息
步骤三:打印输出信息到屏幕

5 代码实现

5.1 Requests获得html页面

使用Requests通用框架,提交url请求,获取网页内容,并使用try-except 异常处理框架,保证程序稳定。

  1. #获取网页源代码
  2. def getHTMLText(url):
  3. try:
  4. headers = {'User-Agent':"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36"}
  5. r = requests.get(url, timeout=30, headers=headers,allow_redirects=False)
  6. print(r.status_code)
  7. r.raise_for_status() # 如果状态不是200,引发HTTPError异常
  8. r.encoding = r.apparent_encoding
  9. #print(r.text[1000:2000])
  10. return r.text
  11. except:
  12. print("网页访问异常!")

5.2 构造所有页面的url地址

分析新闻页面地址可知,其规律为:首页地址的后缀前面加上“_数字”即为其他页面地址,且数字为倒序。

  1. https://www.phei.com.cn/xwxx/index.shtml #首页地址
  2. https://www.phei.com.cn/xwxx/index_54.shtml #第1页地址
  3. https://www.phei.com.cn/xwxx/index_53.shtml #第2页地址
  4. ……
  5. https://www.phei.com.cn/xwxx/index_1.shtml #最后1页地址

定义get_urls()函数,构造所有分页url地址:

  1. def get_urls(pages):
  2. urls = ['https://www.phei.com.cn/xwxx/index.shtml']
  3. for i in range(1,pages):
  4. page = 55-i
  5. url = "https://www.phei.com.cn/xwxx/index_{}.shtml".format(page)
  6. urls.append(url)
  7. #print(urls)
  8. return urls

5.3 BeautifulSoup解析html页面提取信息

网页源代码显示,新闻信息都存储在

  • 中,其中标签名为“li”,属性为“li_b60”
    获取电子工业出版社新闻 - 图4
    因此可以使用bs4的”.find_all()”方法可以定位到信息位置:

    1. def parsePage(html):
    2. soup = BeautifulSoup(html, 'html.parser')
    3. #for tag in soup.find_all(True):
    4. #print(tag.name)
    5. p = soup.find_all('li','li_b60')
    6. #print(p)
    7. print(len(p))
    8. for i in range(len(p)):
    9. print(i)
    10. text = p[i]
    11. #print(text.prettify()) #美观地打印标签树

    同样利用find_all()对定位到的信息进一步准确地提取:

    1. #bs4提取信息
    2. def parsePage(html):
    3. soup = BeautifulSoup(html, 'html.parser')
    4. #for tag in soup.find_all(True):
    5. #print(tag.name)
    6. p = soup.find_all('li','li_b60')
    7. #print(p)
    8. print(len(p))
    9. for i in range(len(p)):
    10. print(i)
    11. text = p[i]
    12. #print(text.prettify()) #美观地打印标签树
    13. #获得新闻时间
    14. time = text.find_all('span')
    15. print(time)
    16. #获得新闻标题
    17. title = text.find_all('p','li_news_title')
    18. print(title)
    19. #获得新闻网址
    20. for link in text.find_all('a'):
    21. link_part = link.get('href')
    22. print(link_part)

    结果如下,可以获得精确的信息。
    但也存在相关问题:
    问题1:信息被一对<>包裹
    问题2:获得的网址不完全
    获取电子工业出版社新闻 - 图5
    针对上述2个问题对代码进行优化:

    1. def parsePage(html):
    2. soup = BeautifulSoup(html, 'html.parser')
    3. #for tag in soup.find_all(True):
    4. #print(tag.name)
    5. p = soup.find_all('li','li_b60')
    6. #print(p)
    7. print(len(p))
    8. for i in range(len(p)):
    9. print(i)
    10. text = p[i]
    11. #print(text.prettify()) #美观地打印标签树
    12. #获得新闻时间
    13. time = text.find_all('span')
    14. time_bs = BeautifulSoup(str(time), 'html.parser')
    15. time_text = time_bs.get_text()
    16. print(time_text)
    17. #获得新闻标题
    18. title = text.find_all('p','li_news_title')
    19. title_bs = BeautifulSoup(str(title), 'html.parser')
    20. title_text = title_bs.get_text()
    21. print(title_text)
    22. #获得新闻网址
    23. for link in text.find_all('a'):
    24. link_part = link.get('href')
    25. html_url = 'https://www.phei.com.cn'+str(link_part)
    26. print(html_url) 作者:穿云蟒 https://www.bilibili.com/read/cv11902002 出处:bilibili

    优化后结果:
    获取电子工业出版社新闻 - 图6
    至此,本程序可以准确提取单一页面的时间、标题、网址信息了。
    下面进一步进行多页面的信息提取

    5.4 构造循环获取html及处理主程序

    1. pages = 2 #输入页面数量
    2. urls = get_urls(pages) #调用get_urls()函数构造url地址
    3. for url in urls: #循环获得页面并进行处理
    4. print(url)
    5. html = getHTMLText(url) #获得网页源代码
    6. parsePage(html) #解析提取网页信息

    全代码:

    1. import requests
    2. from bs4 import BeautifulSoup
    3. #获取网面源代码
    4. def getHTMLText(url):
    5. try:
    6. headers = {'User-Agent':"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36"}
    7. r = requests.get(url, timeout=30, headers=headers,allow_redirects=False)
    8. print(r.status_code)
    9. r.raise_for_status() # 如果状态不是200,引发HTTPError异常
    10. r.encoding = r.apparent_encoding
    11. #print(r.text[1000:2000])
    12. return r.text
    13. except:
    14. print("网页访问异常!")
    15. #bs4提取信息
    16. def parsePage(html):
    17. soup = BeautifulSoup(html, 'html.parser')
    18. #for tag in soup.find_all(True):
    19. #print(tag.name)
    20. p = soup.find_all('li','li_b60')
    21. #print(p)
    22. print(len(p))
    23. for i in range(len(p)):
    24. print(i)
    25. text = p[i]
    26. #print(text.prettify()) #美观地打印标签树
    27. #获得新闻时间
    28. time = text.find_all('span')
    29. time_bs = BeautifulSoup(str(time), 'html.parser')
    30. time_text = time_bs.get_text()
    31. print(time_text)
    32. #获得新闻标题
    33. title = text.find_all('p','li_news_title')
    34. title_bs = BeautifulSoup(str(title), 'html.parser')
    35. title_text = title_bs.get_text()
    36. print(title_text)
    37. #获得新闻网址
    38. for link in text.find_all('a'):
    39. link_part = link.get('href')
    40. html_url = 'https://www.phei.com.cn'+str(link_part)
    41. print(html_url)
    42. def get_urls(pages):
    43. urls = ['https://www.phei.com.cn/xwxx/index.shtml']
    44. for i in range(1,pages):
    45. page = 55-i
    46. url = "https://www.phei.com.cn/xwxx/index_{}.shtml".format(page)
    47. urls.append(url)
    48. #print(urls)
    49. return urls
    50. pages = 3
    51. urls = get_urls(pages)
    52. for url in urls:
    53. print(url)
    54. html = getHTMLText(url) #获得网页源代码
    55. parsePage(html) #解析提取网页信息 作者:穿云蟒 https://www.bilibili.com/read/cv11902002 出处:bilibili