基于BeautifulSoup抓取网站内容的实践(Kanunu8)(1)

简介:

最近闲来无事,拿来练练手。


注:

  1. 由于网站可能会变动,本代码不保证后面一直都能用,仅讲述抓取的思路;

  2. 个人纯属研究使用,请不要应用于商业目的;


使用语言:Python

版本:3.4.3

依赖:BeautifulSouprequests(可以使用pip install进行安装)


代码也比较简单,直接贴上来:

HttpClient.py

1
2
3
4
5
6
7
8
9
10
11
12
# -*- coding: utf-8 -*-
 
import  requests
 
def  make_request(url):
     print ( 'make_request: ' , url)
     =  requests.get(url, timeout = ( 30 90 ))
#     if r.status_code == 200:
     print ( 'content-type: ' , r.headers[ 'content-type' ])
     print ( 'encoding: ' , r.encoding)
     print ( 'apparent_encoding: ' , r.apparent_encoding)
     return  r

Kanunu8.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# -*- coding: utf-8 -*-
 
import  os
import  sys
import  re
import  encodings
 
#为了引用与父目录同级文件夹中的方法
sys.path.append( ".." )
# 解决gb2312乱码问题
encodings.aliases.aliases[ 'gb2312' =  'gb18030'
 
from  bs4  import  BeautifulSoup
from  _pyio  import  open
from  util  import  *
 
 
book_url  =  ''
book_name  =  ''
#屏蔽掉作者的链接
writer_link_pattern  =  re. compile (r '.*/writer/\d+\.html' )
#由于我用的是Windows平台,文件名中不能包含下列非法字符,需要过滤
window_illegal_file_name_pattern  =  re. compile (r '[\\|/|:|\*|\?|"|<|>|\|]' )
     
def  find_tbody(tag):
     if  tag.name  = =  'tbody' :
          if  tag.find( 'tbody' is  None   and  tag.find( 'strong' ).string  = =  '正文' :
              return  True
          elif  '发布时间'  in  tag.get_text():
              return  True
     return  False
 
def  strong_with_no_href(tag):
     return  tag.name  = =  'strong'  and  tag.a  is   None  and  tag.font  is  not  None
     
def  find_title(tag):
     if  tag.h1  is  not  None :
         return  tag.h1.font.string
     elif  tag.h2  is  not  None :
         return  tag.h2.font.string
     else :
        return  tag.find(strong_with_no_href).font.string
 
def  make_soup(html):
     #     , from_encoding='gb18030'
     soup  =  BeautifulSoup(html,  "html.parser" )
     print ( 'original_encoding: ' , soup.original_encoding,  ', declared_html_encoding: ' , soup.declared_html_encoding,  ', from_encoding: ' , soup.from_encoding)
     return  soup
 
def  get_legal_window_file_name(name):
     if  name  is  None :
         return  'unknown'
     return  window_illegal_file_name_pattern.sub('', name)
     
     
if  __name__  = =  '__main__'
     book_url  =  input ( '请输入电子书URL:' )
     
     # 按任意键继续
#     if input('请按任意键开始抓取...'):
#         pass
     
     #获取Html内容
     request  =  HttpClient.make_request(book_url)
     html  =  request.content
     soup  =  make_soup(html)
     # 爬取书名
     book_name  =  soup.find( 'title' ).string
     path  =  './'  +  get_legal_window_file_name(book_name)  +  '.txt'
     
     links  =  []
     #提取所有章节的链接
     for  tmp  in  soup.find_all( 'tbody' ):
         if  len (tmp.find_all( 'tr' )) >  1  :
             all_link  =  tmp.find_all( 'a' )
             if  not  all_link  is  None :
                 links.extend(all_link)
     
     if  book_url.endswith( '.html' ):
         parent_url  =  book_url[ 0 :book_url.rindex( '/' +  1 ]
     else :
         parent_url  =  book_url
     
     with  open (path,  'w' , encoding = "utf-8" ) as f:
         for  link  in  links:
             # 作家链接,忽略
             if  not  writer_link_pattern.match(link[ 'href' ])  is  None :
                 continue
             
             print ( '\n' , link.string)
             url  =  parent_url  +  link[ 'href' ]
             print (url)
             
             response  =  HttpClient.make_request(url)
             chapter_soup  =  make_soup(response.content)
             chapter_name  =  find_title(chapter_soup)
             
             # 章节标题
             f.write( '\n\n' )
             f.write(chapter_name)
             f.write( '\n\n' )
             # 章节内容
             f.write(chapter_soup.find( 'p' ).get_text().replace( '<br/>' , ''))
#             for p in chapter_soup.find('p').contents:
#                 if p == '<br>':
#                     f.write('\n')
#                 elif p is NavigableString:
#                     f.write(p)
#                 elif p is Tag:
#                     f.write(p.string)
         
         f.flush()
         print ( '电子书已成功保存: ' , path)


遇到的问题:

  1. 不同的书(甚至章节)标题内容、字体(h1,h2...)、标签结构都不同;

  2. 编码问题,抓下来是乱码,具体原因请参考


应该是为了增加爬取的难度吧,不过只能针对遇到的问题进行分析、解决;










本文转自 breezy_yuan 51CTO博客,原文链接:http://blog.51cto.com/lbrant/1688440,如需转载请自行联系原作者
目录
相关文章
|
4月前
|
数据采集 开发者 Python
Python爬虫实战:利用Beautiful Soup解析网页数据
在网络爬虫的开发过程中,数据解析是至关重要的一环。本文将介绍如何利用Python的Beautiful Soup库来解析网页数据,包括解析HTML结构、提取目标信息和处理特殊情况,帮助开发者更好地实现爬虫功能。
|
6月前
|
数据采集
Beaustiful Soup爬虫案例
Beaustiful Soup爬虫案例
44 0
|
4天前
|
数据采集 XML 数据可视化
如何用Beautiful Soup解析HTML内容
如何用Beautiful Soup解析HTML内容
10 1
|
14天前
|
存储 XML 自然语言处理
Python网络数据抓取(4):Beautiful Soup
Python网络数据抓取(4):Beautiful Soup
20 2
|
2月前
|
XML 数据采集 前端开发
深入解析网页结构解析模块BeautifulSoup
深入解析网页结构解析模块BeautifulSoup
32 0
|
2月前
|
数据采集 存储 监控
Python爬虫实战:利用BeautifulSoup解析网页数据
在网络信息爆炸的时代,如何快速高效地获取所需数据成为许多开发者关注的焦点。本文将介绍如何使用Python中的BeautifulSoup库来解析网页数据,帮助你轻松实现数据抓取与处理的技术。
|
5月前
|
数据采集 XML 数据格式
python爬虫入门篇:如何解析爬取到的网页数据?试下最简单的BeautifulSoup库!
前面笔记解析了如何使用requests模块向网站发送http请求,获取到网页的HTML数据。这篇我们来如何使用BeautifulSoup模块来从HTML文本中提取我们想要的数据。Beautiful Soup,简称bs4,是Python的一个HTML或XML的解析库,一般用它来从网页中提取数据。
60 1
|
10月前
|
数据采集 前端开发 Python
【Python爬虫】用beautifulsoup4库遇到的错误及处理
在这里对使用beautifulsoup时遇到的问题进行汇总。
|
7月前
|
机器学习/深度学习 数据采集 XML
使用BeautifulSoup解析豆瓣网站的HTML内容并查找图片链接
使用BeautifulSoup解析豆瓣网站的HTML内容并查找图片链接
|
8月前
|
Python
Python使用BeautifulSoup4修改网页内容实战
最近有个小项目,需要爬取页面上相应的资源数据后,保存到本地,然后将原始的HTML源文件保存下来,对HTML页面的内容进行修改将某些标签整个给替换掉。对于这类需要对HTML进行操作的需求,最方便的莫过于BeautifulSoup4的库了。
87 0