根据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'))
相关推荐
用户83562907805115 小时前
Python 实现 PDF 文件加密与解密方法
后端·python
用户83562907805115 小时前
使用 Python 冻结与拆分 Excel 窗格教程
后端·python
你好潘先生1 天前
别再记命令了,用 yeero do 说句人话就能跑脚本,而且不烧 token
服务器·python·命令行
Agent_大师1 天前
WebSocket 行情重连成功,K线缺口不会自动消失
python
荣码1 天前
LLM结构化输出:让AI返回JSON而不是废话,我踩了4个坑
java·python
copyer_xyf1 天前
FastAPI 如何连接 MySQL
后端·python
apocelipes2 天前
常用编程语言和库的正则表达式性能对比
c语言·c++·python·性能优化·golang·开发工具和环境
用户8356290780512 天前
使用 Python 在 PDF 中创建与管理书签
后端·python
MeixianAgent2 天前
Python 回测数据入口怎么验?历史 K 线入库前先做 5 个检查
后端·python
咕白m6252 天前
用 Python 实现一键批量查找与替换 Excel 数据
后端·python