【问题标题】:How to extract downloadable links inside table containing list of links, and scrape multiple pages如何在包含链接列表的表格中提取可下载链接,并抓取多个页面
【发布时间】:2021-01-12 12:36:11
【问题描述】:

点击表格内的特定标题(即本例中的公告)时,我想提取所有 .doc 链接。

我可以按照以下代码为仅一个页面提取第一级中的标题、日期和所有链接:

from lxml import etree
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
import sys
import pandas as pd
from urllib.request import urlparse, urljoin
from bs4 import BeautifulSoup
import requests

frame =[]

chrome_options = Options()
chrome_options.add_argument('--headless')
chrome_options.add_argument('--disable-gpu')
driver = webdriver.Chrome(options = chrome_options)

for page_number in range(1,78):
    url = 'http://example.com/index{}.html'.format(page_number)

driver.get(url)
html = etree.HTML(driver.page_source)

extract_announcements_list = html.xpath('//table[@id="14681"]/tbody/tr/td/table[@width="90%"][position()>=2 and position() <= (last())]')
for i in list:
    date = i.xpath('./tbody/tr/td[3]/text()')
    title = i.xpath('./tbody/tr/td[2]/font/a/@title')
    link = i.xpath('./tbody/tr/td[2]/font/a/@href')
    real_link = 'http://example.com'+ link[0]
    print(title,date,real_link)

frame.append({
    'title': title,
    'link': real_link,
    'date': date,
    **'content': doc_link,** #this is the doc_link I want to extract in the second level
        })

dfs = pd.DataFrame(frame)
dfs.to_csv('myscraper.csv',index=False,encoding='utf-8-sig')

我正在努力寻找解决方案。如果有人能帮我提取第二个链接以获取 .doc 链接的内容('content': doc_link),以及抓取网站中所有页面的方法,我将不胜感激。

非常感谢您!

更新:非常感谢@Ares Zephyr 分享您的代码。这是我根据建议对代码所做的。但它并没有产生任何能够获得内部链接的结果。

from lxml import etree
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
import sys
import pandas as pd
import urllib.request
from bs4 import BeautifulSoup
import requests

frame =[]

chrome_options = Options()
chrome_options.add_argument('--headless')
chrome_options.add_argument('--disable-gpu')
driver = webdriver.Chrome(options = chrome_options)

for page_number in range(1,2):
    url = 'http://example.com/index{}.html'.format(page_number)
    print('Downloading page %s...' % url)

    driver.get(url)
    html = etree.HTML(driver.page_source)
    html_page = urllib.request.urlopen(url)
    soup = BeautifulSoup(html_page, "html.parser")

    extract_announcements_list = html.xpath('//table[@id="14681"]/tbody/tr/td/table[@width="90%"][position()>=2 and position() <= (last())]')
    for i in list:
       date = i.xpath('./tbody/tr/td[3]/text()')
       title = i.xpath('./tbody/tr/td[2]/font/a/@title')
       link = i.xpath('./tbody/tr/td[2]/font/a/@href')
       real_link = 'http://example.com'+ link[0]

          soup = BeautifulSoup(requests.get(real_link).content, 'html.parser')
          for doc_link in soup.findAll('a'):
             thelink = doc_link.get('href')

             frame.append({
               'title': title,
               'link': real_link,
               'date': date,
               'doclink': thelink,
               })

dfs = pd.DataFrame(frame)
dfs.to_csv('myscraper.csv',index=False,encoding='utf-8-sig')

【问题讨论】:

  • 为什么不是所有的东西都在 for 循环中?你只得到最后一页。对于范围内的 page_number(1,78):
  • @arundeepchohan 以前我可以将此代码用于 page_number in range(1,78): 并且它在其他页面中运行良好,我只是不太确定我在这里做错了什么,并且我只能在 Python 中获取最后一页,并且在导出到 csv 文件时,只出现最后一页的最后公告+日期+链接。我在想也许我把循环或其他东西放在了里面。非常感谢您能帮我解决这个问题。
  • 你应该把它放在 for 循环中。您每次循环并重新初始化值,然后只附加一次。
  • 非常感谢@arundeepchohan。它现在正在工作。只是想知道,您能否在单击表格中的链接时建议如何修改我的代码以废弃所有网页并获取所有 .doc 链接?您能提供的任何帮助将不胜感激。
  • @arundeepchohan 更新:我刚刚通过按顺序缩进修改了我的代码。我现在可以报废所有页面了。现在问题只剩下提取所有 .doc 链接了。非常感谢您能就此提出建议。

标签: python selenium web-scraping beautifulsoup python-requests


【解决方案1】:

您需要在代码中缩进这一段,以便 append 函数可以处理所有抓取的数据。我相信这也是@arundeep-chohan 想要强调的。

frame.append({
    'title': announcement_title,
    'link': real_link,
    'date': announcement_date,
    **'content': doc_link,** #this is the doc_link I want to extract in the second level
        })

查找doc文件的逻辑如下。请修改并使用它。这是我用来下载 pdf 文件的代码的一部分。

for link in soup.findAll('a'):
  theLink = link.get('href')
  name= link.string

  # Logic to find .pdf files
 
  if theLink[-4:]  == ".pdf" or theLink[-4:] == ".pdf":
    if theLink[-4:] ==".pdf":
      fileExtension = ".pdf"

【讨论】:

  • 我的错,我一开始并没有意识到这一点。它现在按预期工作。只是想知道,在单击表格中的链接时,您能否建议如何修改我的代码以废弃所有网页并获取所有 .doc 链接?您能提供的任何帮助将不胜感激。
  • 由于该站点是外语的,因此很难浏览页面和调试。但是,我确实注意到存在 xlsx 文件,它们都作为链接存储在网站上。您可以查找带有“href”且扩展名为 .doc 或 .docx 的标签,并且您可以获得所有网址/可能还可以下载文件。
  • 更新:我刚刚通过按顺序缩进修改了我的代码。我现在可以报废所有页面了。现在问题只剩下提取所有 .doc 链接了。非常感谢您能就此提出建议。
  • @Tracy 我已经更新了上面的代码,加入了一个可以帮助您找到 doc 文件的部分。只需适当地使用扩展名。 .doc 或 .docx
  • 谢谢,您的编辑对我来说真的很重要。我只是想知道您是否可以查看我更新的代码,因为我在运行时遇到错误。我认为这是由于发送到页面的请求。我已尝试删除前 2 页。
猜你喜欢
  • 2019-06-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-02
  • 2014-05-15
  • 1970-01-01
  • 2017-09-07
相关资源
最近更新 更多