根据xlsx文件第一列的网址爬虫

selenium+Xpath

在与该ipynb文件同文件下新增一个111.xlsx,第一列放一堆需要爬虫的同样式网页

然后使用selenium+Xpath爬虫

from selenium import webdriver
from selenium.webdriver.common.by import By
import openpyxl
import time

def crawl_data(driver, url):
    driver.get(url)
    time.sleep(5)  # 等待页面加载

    # 爬取指定的XPath内容
    xpath1 = '//*[@id="main"]/div/div/div[2]/div[1]/div/div[1]/div'
    xpath2 = '//*[@id="main"]/div/div/div[2]/div[1]/div/div[1]/p/span'
    xpath3 = '//*[@id="descriptionDiv"]/p'
    xpath4 = '//*[@id="introductionDiv"]/p'
    
    content1 = driver.find_element(By.XPATH, xpath1).text
    content2 = driver.find_element(By.XPATH, xpath2).text
    content3 = driver.find_element(By.XPATH, xpath3).text
    content4 = driver.find_element(By.XPATH, xpath4).text

    return content1, content2, content3, content4

# 启动Chrome浏览器
chrome_options = webdriver.ChromeOptions()
driver = webdriver.Chrome(options=chrome_options)

# 打开Excel文件
file_path = "111.xlsx"
wb = openpyxl.load_workbook(file_path)
ws = wb.active

# 获取第一列的网址
urls = [cell.value for cell in ws["A"]]

# 逐个处理每个网址
for i, url in enumerate(urls, start=1):
    print(f"处理第{i}个网址: {url}")
    
    url_str = str(url) if url is not None else ""
    
    # 爬取数据
    data1, data2, data3, data4 = crawl_data(driver, url_str)

    # 写回Excel文件
    ws.cell(row=i, column=2, value=data1)
    ws.cell(row=i, column=3, value=data2)
    ws.cell(row=i, column=4, value=data3)
    ws.cell(row=i, column=5, value=data4)

# 保存Excel文件
wb.save(file_path)

# 关闭浏览器
driver.quit()

使用Xpath方法相比css定位的好处:如果页面的层级结构非常复杂,XPath提供了更复杂的选择和过滤方式,可以更灵活地定位元素

相比id、class定位的好处:XPath可以根据元素的属性值进行定位,这在某些情况下很有用,尤其是在没有独特标识符(如ID)的情况下

同样使用selenium其它定位的方法

按ID、类名

# 以ID定位元素
element_by_id = driver.find_element(By.ID, 'articleContentId')
print("Element by ID:", element_by_id.text)

# 以类名定位元素
element_by_class = driver.find_element(By.CLASS_NAME, 'title-article')
print("Element by Class Name:", element_by_class.text)

按css选择器

# 以CSS选择器定位元素
element_by_css = driver.find_element(By.CSS_SELECTOR, '#articleContentId')
print("Element by CSS Selector:", element_by_css.text)

不用selenium

Requests + BeautifulSoup

使用BeautifulSoup时,通常通过选择器(CSS选择器)而不是XPath来提取元素

import requests
from bs4 import BeautifulSoup

url = "https://example.com"
response = requests.get(url)
soup = BeautifulSoup(response.text, 'html.parser')

# 使用CSS选择器
title_element = soup.select_one('#articleContentId')
title = title_element.text if title_element else "Title not found"

paragraphs = soup.select('#articleContentId + div.content p')

# 输出结果
print(f"Title: {title}")
for paragraph in paragraphs:
    print(paragraph.text)

Scrapy

在Scrapy中,可以使用XPath或CSS选择器,具体取决于你的喜好或页面的结构。

XPath

import scrapy

class MySpider(scrapy.Spider):
    name = 'myspider'
    start_urls = ['https://example.com']

    def parse(self, response):
        # 使用XPath
        title = response.xpath('//*[@id="articleContentId"]/text()').get()
        paragraphs = response.xpath('//*[@id="articleContentId"]/following-sibling::div[@class="content"]/p/text()').getall()

        # 输出结果
        print(f"Title: {title}")
        for paragraph in paragraphs:
            print(paragraph)

css

import scrapy

class MySpider(scrapy.Spider):
    name = 'myspider'
    start_urls = ['https://example.com']

    def parse(self, response):
        # 使用CSS选择器
        title = response.css('#articleContentId::text').get()
        paragraphs = response.css('#articleContentId + div.content p::text').getall()

        # 输出结果
        print(f"Title: {title}")
        for paragraph in paragraphs:
            print(paragraph)

Pyppeteer / Playwright

使用Pyppeteer或Playwright时,你可以通过JavaScript在页面上执行脚本来获取数据,而不是直接使用XPath

XPath

from pyppeteer import launch

async def crawl_data(url):
    browser = await launch()
    page = await browser.newPage()
    await page.goto(url)

    # 使用JavaScript执行脚本获取内容
    title = await page.evaluate('document.evaluate("//*[@id=\"articleContentId\"]", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue.textContent')
    paragraphs = await page.evaluate('Array.from(document.evaluate("//*[@id=\"articleContentId\"]//p", document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null)).map(p => p.textContent)')

    # 输出结果
    print(f"Title: {title}")
    for paragraph in paragraphs:
        print(paragraph)

    await browser.close()

# 使用asyncio来运行异步代码
import asyncio
asyncio.get_event_loop().run_until_complete(crawl_data('https://example.com'))

element选择器

Element选择器实际上是通过HTML元素的标签名来选择元素,而不是通过ID或类名。

HTML元素的标签名就是元素的名称,通常是由尖括号括起来的部分。下述h1、p、a就是HTML元素的标签名

<h1>这是一个标题</h1>

<p>这是一个段落</p>

<a href="https://www.example.com">这是一个链接</a>

所以,如果你想使用element选择器,你可以这样修改代码:

from pyppeteer import launch

async def crawl_data(url):
    browser = await launch()
    page = await browser.newPage()
    await page.goto(url)

    # 使用JavaScript执行脚本获取内容
    title = await page.evaluate('document.querySelector("h1#articleContentId").textContent')
    paragraphs = await page.evaluate('Array.from(document.querySelector("h1#articleContentId + div.content").querySelectorAll("p")).map(p => p.textContent)')

    # 输出结果
    print(f"Title: {title}")
    for paragraph in paragraphs:
        print(paragraph)

    await browser.close()

# 使用asyncio来运行异步代码
import asyncio
asyncio.get_event_loop().run_until_complete(crawl_data('https://example.com'))

在这个例子中,我们使用了document.querySelector("h1#articleContentId")来选择ID为articleContentId的h1元素,以及document.querySelector("h1#articleContentId + div.content").querySelectorAll("p")来选择与该h1元素相邻的div元素内的所有p元素。

css

from pyppeteer import launch

async def crawl_data(url):
    browser = await launch()
    page = await browser.newPage()
    await page.goto(url)

    # 使用JavaScript执行脚本获取内容
    title = await page.evaluate('document.querySelector("#articleContentId").textContent')
    paragraphs = await page.evaluate('Array.from(document.querySelectorAll("#articleContentId p")).map(p => p.textContent)')

    # 输出结果
    print(f"Title: {title}")
    for paragraph in paragraphs:
        print(paragraph)

    await browser.close()

# 使用asyncio来运行异步代码
import asyncio
asyncio.get_event_loop().run_until_complete(crawl_data('https://example.com'))
相关推荐
奋斗的小花生几秒前
c++ 多态性
开发语言·c++
魔道不误砍柴功3 分钟前
Java 中如何巧妙应用 Function 让方法复用性更强
java·开发语言·python
闲晨6 分钟前
C++ 继承:代码传承的魔法棒,开启奇幻编程之旅
java·c语言·开发语言·c++·经验分享
_.Switch28 分钟前
高级Python自动化运维:容器安全与网络策略的深度解析
运维·网络·python·安全·自动化·devops
老猿讲编程33 分钟前
一个例子来说明Ada语言的实时性支持
开发语言·ada
Chrikk2 小时前
Go-性能调优实战案例
开发语言·后端·golang
幼儿园老大*2 小时前
Go的环境搭建以及GoLand安装教程
开发语言·经验分享·后端·golang·go
canyuemanyue2 小时前
go语言连续监控事件并回调处理
开发语言·后端·golang
杜杜的man2 小时前
【go从零单排】go语言中的指针
开发语言·后端·golang
测开小菜鸟2 小时前
使用python向钉钉群聊发送消息
java·python·钉钉