使用 Python 进行网络爬虫——从0构建简单爬虫

Python (59) 2023-12-07 10:12

Hi,大家好,我是编程小6,很荣幸遇见你,我把这些年在开发过程中遇到的问题或想法写出来,今天说一说使用 Python 进行网络爬虫——从0构建简单爬虫,希望能够帮助你!!!。

从零开始用 Python 构建一个简单的网络爬虫

要在 Python 中构建一个简单的网络爬虫,我们至少需要一个库来从 URL 下载 HTML,还需要一个 HTML 解析库来提取链接。Python 提供标准库urllib用于发出 HTTP 请求和html.parser用于解析 HTML。仅使用标准库构建的 Python 爬虫示例可以在Github上找到。

用于请求和 HTML 解析的标准 Python 库对开发人员不太友好。其他流行的库,如requests、品牌为人类的 HTTP 和Beautiful Soup提供了更好的开发者体验。

如果您想了解更多信息,可以查看有关最佳 Python HTTP 客户端的指南。

您可以在本地安装这两个库。

pip install requests bs4

可以按照前面的架构图搭建一个基本的爬虫。


import logging
from urllib.parse 
import urljoin
import requests
from bs4 
import BeautifulSoup
 
logging.basicConfig(
    
format=
'%(asctime)s %(levelname)s:%(message)s',
    level=logging.INFO)
 
class 
Crawler:
 
    
def 
__init__(
self, urls=[]):
        self.visited_urls = []
        self.urls_to_visit = urls
 
    
def 
download_url(
self, url):
        
return requests.get(url).text
 
    
def 
get_linked_urls(
self, url, html):
        soup = BeautifulSoup(html, 
'html.parser')
        
for link 
in soup.find_all(
'a'):
            path = link.get(
'href')
            
if path 
and path.startswith(
'/'):
                path = urljoin(url, path)
            
yield path
 
    
def 
add_url_to_visit(
self, url):
        
if url 
not 
in self.visited_urls 
and url 
not 
in self.urls_to_visit:
            self.urls_to_visit.append(url)
 
    
def 
crawl(
self, url):
        html = self.download_url(url)
        
for url 
in self.get_linked_urls(url, html):
            self.add_url_to_visit(url)
 
    
def 
run(
self):
        
while self.urls_to_visit:
            url = self.urls_to_visit.pop(
0)
            logging.info(
f'Crawling: {url}')
            
try:
                self.crawl(url)
            
except Exception:
                logging.exception(
f'Failed to crawl: {url}')
            
finally:
                self.visited_urls.append(url)
 
if __name__ == 
'__main__':
    Crawler(urls=[
'https://www.imdb.com/']).run()

上面的代码定义了一个 Crawler 类,其中包含使用 requests 库的 download_url、使用 Beautiful Soup 库的 get_linked_urls 和过滤 URL 的 add_url_to_visit 的帮助方法。要访问的 URL 和已访问的 URL 存储在两个单独的列表中。您可以在终端上运行爬虫。

python crawler.py

爬虫为每个访问的 URL 记录一行。

2020-12-04 18:10:10,737 INFO:Crawling: https://www.imdb.com/
2020-12-04 18:10:11,599 INFO:Crawling: https://www.imdb.com/?ref_=nv_home
2020-12-04 18:10:12,868 INFO:Crawling: https://www.imdb.com/calendar/?ref_=nv_mv_cal
2020-12-04 18:10:13,526 INFO:Crawling: https://www.imdb.com/list/ls016522954/?ref_=nv_tvv_dvd
2020-12-04 18:10:19,174 INFO:Crawling: https://www.imdb.com/chart/top/?ref_=nv_mv_250
2020-12-04 18:10:20,624 INFO:Crawling: https://www.imdb.com/chart/moviemeter/?ref_=nv_mv_mpm
2020-12-04 18:10:21,556 INFO:Crawling: https://www.imdb.com/feature/genre/?ref_=nv_ch_gr

代码非常简单,但是在成功爬取一个完整的网站之前,还有许多性能和可用性问题需要解决。

  • 爬虫很慢,不支持并行。从时间戳可以看出,爬取每个 URL 大约需要一秒钟。每次爬虫发出请求时,它都会等待请求被解析,并且在两者之间不做任何工作。
  • 下载 URL 逻辑没有重试机制,URL 队列不是真正的队列,在 URL 数量多的情况下效率不高。
  • 链接提取逻辑不支持通过删除 URL 查询字符串参数来标准化 URL,不处理以 # 开头的 URL,不支持按域​过滤 URL 或过滤对静态文件的请求。
  • 爬虫不会识别自己并忽略 robots.txt 文件。

下一篇,我们将了解 Scrapy 如何提供所有这些功能并使其易于扩展以适应您的自定义爬网。

今天的分享到此就结束了,感谢您的阅读,如果确实帮到您,您可以动动手指转发给其他人。

发表回复