Web抓取(Web Scraping)是一种从网站提取数据的技术。Python有许多用于Web抓取的库,其中最常用的是BeautifulSoup和Scrapy。
BeautifulSoup
BeautifulSoup是一个用于解析HTML和XML文档的Python库,适合处理简单的Web抓取任务。它将复杂的HTML文档转换成一个可遍历的解析树,可以方便地找到需要的元素。
安装BeautifulSoup
要使用BeautifulSoup,首先需要安装它以及请求库requests:
pip install beautifulsoup4
pip install requests
导入BeautifulSoup
from bs4 import BeautifulSoup
import requests
获取网页内容
首先需要获取网页的HTML内容,可以使用requests库:
url = 'http://example.com'
response = requests.get(url)
html_content = response.content
解析HTML
使用BeautifulSoup解析HTML内容:
soup = BeautifulSoup(html_content, 'html.parser')
查找元素
BeautifulSoup提供了多种查找元素的方法,如find
、find_all
、select
等。
# 查找第一个<p>标签
p_tag = soup.find('p')
print(p_tag.text)
# 查找所有<a>标签
a_tags = soup.find_all('a')
for tag in a_tags:
print(tag.get('href'))
# 使用CSS选择器
header = soup.select_one('h1')
print(header.text)
处理属性
可以方便地获取标签的属性:
img_tag = soup.find('img')
print(img_tag['src'])
示例:抓取一个博客的标题和链接
以下是一个简单的示例,展示如何抓取一个博客页面的所有文章标题和链接:
url = 'http://example-blog.com'
response = requests.get(url)
soup = BeautifulSoup(response.content, 'html.parser')
articles = soup.find_all('article')
for article in articles:
title = article.find('h2').text
link = article.find('a')['href']
print(f'Title: {title}, Link: {link}')
Scrapy
Scrapy是一个功能强大的Web抓取和Web爬虫框架,适用于复杂的抓取任务。它具有高性能、可扩展性强、支持异步处理等特点。
安装Scrapy
使用pip安装Scrapy:
pip install scrapy
创建Scrapy项目
首先需要创建一个Scrapy项目:
scrapy startproject myproject
cd myproject
创建爬虫
在Scrapy项目中,可以创建一个新的爬虫:
scrapy genspider myspider example.com
这将在spiders
目录下生成一个名为myspider.py
的文件。
编写爬虫
打开myspider.py
,可以看到一个基本的爬虫模板。我们将修改这个模板来实现抓取任务。
import scrapy
class MySpider(scrapy.Spider):
name = 'myspider'
start_urls = ['http://example.com']
def parse(self, response):
# 解析响应
for article in response.css('article'):
title = article.css('h2::text').get()
link = article.css('a::attr(href)').get()
yield {
'title': title,
'link': link
}
运行爬虫
在命令行中运行爬虫:
scrapy crawl myspider -o output.json
这将抓取example.com
并将结果保存到output.json
文件中。
Scrapy中的重要概念
- Item:定义抓取的数据结构。
- Spider:定义如何抓取网站的爬虫。
- Pipeline:定义数据处理和存储的流程。
- Middleware:处理请求和响应的中间件。
定义Item
可以在items.py
中定义Item:
import scrapy
class MyprojectItem(scrapy.Item):
title = scrapy.Field()
link = scrapy.Field()
然后在爬虫中使用Item:
from myproject.items import MyprojectItem
class MySpider(scrapy.Spider):
name = 'myspider'
start_urls = ['http://example.com']
def parse(self, response):
for article in response.css('article'):
item = MyprojectItem()
item['title'] = article.css('h2::text').get()
item['link'] = article.css('a::attr(href)').get()
yield item
使用Pipeline处理数据
在pipelines.py
中定义Pipeline:
class MyprojectPipeline:
def process_item(self, item, spider):
# 处理item
return item
在settings.py
中启用Pipeline:
ITEM_PIPELINES = {
'myproject.pipelines.MyprojectPipeline': 300,
}
示例:抓取一个电商网站的商品信息
以下是一个完整的示例,展示如何使用Scrapy抓取一个电商网站的商品信息。
首先定义Item:
# items.py
import scrapy
class ProductItem(scrapy.Item):
name = scrapy.Field()
price = scrapy.Field()
availability = scrapy.Field()
然后编写爬虫:
# spiders/products_spider.py
import scrapy
from myproject.items import ProductItem
class ProductsSpider(scrapy.Spider):
name = 'products'
start_urls = ['http://example-ecommerce.com/products']
def parse(self, response):
for product in response.css('div.product'):
item = ProductItem()
item['name'] = product.css('h3.product-name::text').get()
item['price'] = product.css('span.product-price::text').get()
item['availability'] = product.css('span.availability::text').get()
yield item
# 处理分页
next_page = response.css('a.next-page::attr(href)').get()
if next_page:
yield response.follow(next_page, self.parse)
最后启用Pipeline并运行爬虫:
# pipelines.py
class ProductPipeline:
def process_item(self, item, spider):
# 处理商品信息
return item
# settings.py
ITEM_PIPELINES = {
'myproject.pipelines.ProductPipeline': 300,
}
# 运行爬虫
scrapy crawl products -o products.json
BeautifulSoup和Scrapy各有优缺点,BeautifulSoup适合处理简单的抓取任务,使用方便,代码简洁;而Scrapy则更适合处理复杂的抓取任务,具有强大的功能和高效的性能。在实际项目中,可以根据具体需求选择合适的工具,甚至结合使用这两个库,以充分发挥各自的优势。