如何爬取网页数据

如何爬取网页数据

爬取网页数据(Web Scraping)是一项常见的技术任务,下面我将详细介绍从基础到进阶的网页爬取方法。

一、基础网页爬取方法

1.1 使用Python requests库

import requests

url = "https://example.com"
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
}

response = requests.get(url, headers=headers)

if response.status_code == 200:
    html_content = response.text
    print(html_content[:500])  # 打印前500个字符
else:
    print(f"请求失败,状态码: {response.status_code}")

1.2 使用BeautifulSoup解析HTML

from bs4 import BeautifulSoup

# 假设html_content是上面获取的网页内容
soup = BeautifulSoup(html_content, 'html.parser')

# 提取标题
title = soup.title.string if soup.title else "无标题"
print(f"网页标题: {title}")

# 提取所有链接
for link in soup.find_all('a', href=True):
    print(link['href'])

二、处理动态加载内容

2.1 使用Selenium

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
import time

chrome_options = Options()
chrome_options.add_argument("--headless")  # 无头模式

driver = webdriver.Chrome(options=chrome_options)
driver.get("https://example.com")

# 等待JavaScript加载
time.sleep(2)

# 获取渲染后的页面源码
html_content = driver.page_source

# 可以用BeautifulSoup继续解析
soup = BeautifulSoup(html_content, 'html.parser')
# ...解析逻辑...

driver.quit()  # 关闭浏览器

2.2 使用Pyppeteer(无头Chrome)

import asyncio
from pyppeteer import launch

async def scrape():
    browser = await launch(headless=True)
    page = await browser.newPage()
    await page.goto('https://example.com')
    
    # 等待特定元素出现
    await page.waitForSelector('#content')
    
    content = await page.content()
    # ...处理content...
    
    await browser.close()

asyncio.get_event_loop().run_until_complete(scrape())

三、处理常见反爬机制

3.1 使用代理IP

proxies = {
    'http': 'http://10.10.1.10:3128',
    'https': 'http://10.10.1.10:1080',
}

response = requests.get(url, headers=headers, proxies=proxies)

3.2 随机User-Agent

from fake_useragent import UserAgent

ua = UserAgent()
headers = {'User-Agent': ua.random}

3.3 处理验证码

# 使用第三方验证码识别服务
def solve_captcha(image_url):
    # 这里可以使用2captcha、打码兔等API
    pass

四、使用Scrapy框架

4.1 创建Scrapy项目

scrapy startproject myproject
cd myproject
scrapy genspider example example.com

4.2 编写Spider

import scrapy

class ExampleSpider(scrapy.Spider):
    name = "example"
    allowed_domains = ["example.com"]
    start_urls = ["https://example.com"]

    def parse(self, response):
        # 提取数据
        title = response.css('title::text').get()
        links = response.css('a::attr(href)').getall()
        
        yield {
            'title': title,
            'links': links
        }
        
        # 跟进链接
        for link in links:
            yield response.follow(link, callback=self.parse)

五、数据存储

5.1 存储到CSV

import csv

with open('output.csv', 'w', newline='', encoding='utf-8') as f:
    writer = csv.writer(f)
    writer.writerow(['Title', 'URL'])
    writer.writerow([title, url])

5.2 存储到数据库

import sqlite3

conn = sqlite3.connect('scraped_data.db')
cursor = conn.cursor()

# 创建表
cursor.execute('''CREATE TABLE IF NOT EXISTS pages
             (id INTEGER PRIMARY KEY AUTOINCREMENT,
              title TEXT, url TEXT, content TEXT)''')

# 插入数据
cursor.execute("INSERT INTO pages (title, url, content) VALUES (?, ?, ?)",
              (title, url, content))
conn.commit()
conn.close()

六、高级技巧

6.1 分布式爬取

使用Scrapy-Redis实现分布式爬虫:

# settings.py
SCHEDULER = "scrapy_redis.scheduler.Scheduler"
DUPEFILTER_CLASS = "scrapy_redis.dupefilter.RFPDupeFilter"
REDIS_URL = 'redis://localhost:6379'

# spider.py
from scrapy_redis.spiders import RedisSpider

class MySpider(RedisSpider):
    name = 'myspider'
    redis_key = 'myspider:start_urls'

6.2 增量爬取

# 使用数据库记录已爬取URL
def is_url_crawled(url):
    # 检查数据库
    return False  # 假设未爬取

if not is_url_crawled(url):
    # 爬取逻辑
    pass

七、法律与道德注意事项

  1. 检查robots.txt - https://example.com/robots.txt
  2. 限制请求频率 - 使用time.sleep()控制爬取速度
  3. 尊重版权 - 不要爬取受版权保护的内容
  4. 不爬取个人隐私数据 - 遵守数据保护法规
  5. 考虑使用API - 优先使用网站提供的官方API

八、完整示例

import requests
from bs4 import BeautifulSoup
import time
import random
from fake_useragent import UserAgent

ua = UserAgent()

def scrape_website(base_url, max_pages=10):
    visited = set()
    to_visit = {base_url}
    data = []
    
    while to_visit and len(data) < max_pages:
        url = to_visit.pop()
        
        if url in visited:
            continue
            
        try:
            headers = {'User-Agent': ua.random}
            response = requests.get(url, headers=headers, timeout=10)
            
            if response.status_code == 200:
                soup = BeautifulSoup(response.text, 'html.parser')
                
                # 提取数据
                title = soup.title.string if soup.title else "无标题"
                data.append({'url': url, 'title': title})
                
                # 提取新链接
                for link in soup.find_all('a', href=True):
                    href = link['href']
                    if href.startswith('http') and base_url in href:
                        to_visit.add(href)
                
                visited.add(url)
                print(f"已爬取: {url}")
                
                # 随机延迟
                time.sleep(random.uniform(1, 3))
                
        except Exception as e:
            print(f"爬取 {url} 失败: {e}")
    
    return data

# 使用示例
results = scrape_website("https://example.com", max_pages=5)
for item in results:
    print(f"{item['title']} - {item['url']}")

以上是网页爬取的基本方法和技巧,实际应用中需要根据目标网站的具体情况进行调整。

### 构建任务失败解决方案 当遇到 `Execution failed for task ':app:shrinkReleaseRes'` 错误时,这通常意味着资源压缩过程中出现了问题。此错误可能由多种原因引起,包括但不限于配置不正确、依赖冲突或特定于项目的其他因素。 #### 可能的原因分析 1. **ProGuard 或 R8 配置不当** ProGuard 和 R8 是用于优化和混淆代码以及减少 APK 大小的工具。如果这些工具的配置存在问题,可能会导致资源无法正常处理[^1]。 2. **重复资源** 如果项目中有多个模块定义了相同的资源名称,可能导致冲突并引发该错误。检查是否存在重名的 drawable、string 等资源文件[^2]。 3. **第三方库兼容性** 某些第三方库可能与当前使用的 Gradle 插件版本或其他库存在兼容性问题,从而影响到资源打包过程中的行为[^3]。 4. **Gradle 缓存问题** 有时旧缓存数据会干扰新编译的结果,尝试清理本地仓库和重新同步项目可以帮助排除此类潜在障碍[^4]。 #### 推荐的操作方法 为了有效解决问题,建议按照以下步骤逐一排查: ```bash # 清理项目构建目录 ./gradlew clean # 删除 .gradle 文件夹下的所有内容以清除缓存 rm -rf ~/.gradle/caches/ ``` 调整 `build.gradle` 中的相关设置也是一个重要环节: ```groovy android { ... buildTypes { release { minifyEnabled true // 是否启用代码缩减 shrinkResources true // 是否开启资源压缩 proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' // 尝试禁用 shrinkResources 来测试是否为资源压缩引起的错误 // shrinkResources false } } } ``` 此外,在 `proguard-rules.pro` 文件内添加必要的保留规则,防止关键类被意外移除: ```text -keep class com.example.yourpackage.** { *; } # 替换为你自己的包路径 -dontwarn androidx.**,com.google.** # 忽略警告信息 ``` 最后,确保所使用的 Android Studio 版本是最新的稳定版,并且已经应用了所有的补丁更新。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Fro.Heart

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值