使用Python进行网页抓取[关闭]


183

我想从网站上获取每天的日出/日落时间。是否可以使用Python抓取Web内容?使用什么模块?有没有可用的教程?


3
Python有几种用于Web抓取的选项。为了回答类似的问题,我在这里列举了一些选项。
filippo 2010年

为什么不只使用Python标准库中的内置HTML解析器?当然,对于一项如此简单且不频繁的任务(每天仅执行一次),我几乎没有理由寻找任何其他工具。docs.python.org/2.7/library/htmlparser.html
ArtOfWarfare 2015年

希望这篇文章对某人可能有用。一个适合初学者的好教程。samranga.blogspot.com/2015/08/web-scraping-beginner-python.html它使用漂亮的汤python库进行python的网络抓取。
Samitha Chathuranga

Answers:


187

结合使用urllib2和出色的BeautifulSoup库:

import urllib2
from BeautifulSoup import BeautifulSoup
# or if you're using BeautifulSoup4:
# from bs4 import BeautifulSoup

soup = BeautifulSoup(urllib2.urlopen('http://example.com').read())

for row in soup('table', {'class': 'spad'})[0].tbody('tr'):
    tds = row('td')
    print tds[0].string, tds[1].string
    # will print date and sunrise

7
小注释:使用请求包可以通过将第6行替换为:soup = BeautifulSoup(requests.get(' example.com')。text
D Coetzee 2012年

4
谢谢你的提示。当我在上面编写了代码片段时,请求包还不存在;-)

1
@DerrickCoetzee-您的简化会引发MissingSchema错误(至少在我的安装中如此)。该作品:soup = BeautifulSoup(requests.get('http://example.com').text)
kmote 2012年

@kmote:那是我键入的内容,但是我忘记backticks了代码周围的内容,并将其转换为链接。谢谢!
D Coetzee

您如何确定内容将在td和tr中。可以在ul和li中对吗?
Shashank Hegde 2014年

62

我真的会推荐Scrapy。

引用删除的答案:

  • Scrapy爬行比机械化最快,因为它使用异步操作(在Twisted之上)。
  • Scrapy在libxml2之上对解析(x)html提供了更好,最快的支持。
  • Scrapy是具有完整unicode的成熟框架,可处理重定向,gzip压缩响应,奇数编码,集成的http缓存等。
  • 一旦进入Scrapy,您可以在不到5分钟的时间内编写蜘蛛,下载图像,创建缩略图并将提取的数据直接导出到csv或json。

13
我没有注意到这个问题已经2岁了,仍然觉得应该在这里命名Scrapy,以防其他人遇到相同的问题。
Sjaak Trekhaak,2011年

4
Scrapy是一个框架,因此非常可怕,并认为它比您的项目更重要。由于Twisted的可怕(不必要的)局限性,所以它是一个框架。
user1244215

4
@ user1244215:这是一个框架,因为框架很好。如果您不想将其用作框架,那么没有什么可以阻止您将所有代码都阻塞到一个文件中。
搅拌器

1
但是它不支持Python3.x。

17

我将网络抓取工作中的脚本收集到了这个位桶库中

针对您的案例的示例脚本:

from webscraping import download, xpath
D = download.Download()

html = D.get('http://example.com')
for row in xpath.search(html, '//table[@class="spad"]/tbody/tr'):
    cols = xpath.search(row, '/td')
    print 'Sunrise: %s, Sunset: %s' % (cols[1], cols[2])

输出:

Sunrise: 08:39, Sunset: 16:08
Sunrise: 08:39, Sunset: 16:09
Sunrise: 08:39, Sunset: 16:10
Sunrise: 08:40, Sunset: 16:10
Sunrise: 08:40, Sunset: 16:11
Sunrise: 08:40, Sunset: 16:12
Sunrise: 08:40, Sunset: 16:13

10

我强烈建议您检查pyquery。它使用类似jquery(又称css)的语法,这对于那些来自该背景的人来说确实很容易。

对于您的情况,它将类似于:

from pyquery import *

html = PyQuery(url='http://www.example.com/')
trs = html('table.spad tbody tr')

for tr in trs:
  tds = tr.getchildren()
  print tds[1].text, tds[2].text

输出:

5:16 AM 9:28 PM
5:15 AM 9:30 PM
5:13 AM 9:31 PM
5:12 AM 9:33 PM
5:11 AM 9:34 PM
5:10 AM 9:35 PM
5:09 AM 9:37 PM

7

您可以使用urllib2发出HTTP请求,然后获得Web内容。

您可以这样获得:

import urllib2
response = urllib2.urlopen('http://example.com')
html = response.read()

Beautiful Soup是一个Python HTML解析器,应该适合于屏幕抓取。

特别是,是他们的解析HTML文档的教程。

祝好运!


设置读取字节的最大值可能是个主意。response.read(100000000)之类的东西,这样用于ISO的URL不会填满您的RAM。采矿愉快。
安德鲁·帕特

4

我将Scrapemark(查找网址-py2)和httlib2(下载图像-py2 + 3)结合使用。scrapemark.py有500行代码,但是使用正则表达式,因此它可能没有那么快,没有进行测试。

抓取网站的示例:

import sys
from pprint import pprint
from scrapemark import scrape

pprint(scrape("""
    <table class="spad">
        <tbody>
            {*
                <tr>
                    <td>{{[].day}}</td>
                    <td>{{[].sunrise}}</td>
                    <td>{{[].sunset}}</td>
                    {# ... #}
                </tr>
            *}
        </tbody>
    </table>
""", url=sys.argv[1] ))

用法:

python2 sunscraper.py http://www.example.com/

结果:

[{'day': u'1. Dez 2012', 'sunrise': u'08:18', 'sunset': u'16:10'},
 {'day': u'2. Dez 2012', 'sunrise': u'08:19', 'sunset': u'16:10'},
 {'day': u'3. Dez 2012', 'sunrise': u'08:21', 'sunset': u'16:09'},
 {'day': u'4. Dez 2012', 'sunrise': u'08:22', 'sunset': u'16:09'},
 {'day': u'5. Dez 2012', 'sunrise': u'08:23', 'sunset': u'16:08'},
 {'day': u'6. Dez 2012', 'sunrise': u'08:25', 'sunset': u'16:08'},
 {'day': u'7. Dez 2012', 'sunrise': u'08:26', 'sunset': u'16:07'}]

1

通过使用使您的生活更轻松 CSS Selectors

我知道我来晚了,但是我对你有很好的建议。

使用BeautifulSoup已经有人建议我宁愿用CSS Selectors刮里面的数据HTML

import urllib2
from bs4 import BeautifulSoup

main_url = "http://www.example.com"

main_page_html  = tryAgain(main_url)
main_page_soup = BeautifulSoup(main_page_html)

# Scrape all TDs from TRs inside Table
for tr in main_page_soup.select("table.class_of_table"):
   for td in tr.select("td#id"):
       print(td.text)
       # For acnhors inside TD
       print(td.select("a")[0].text)
       # Value of Href attribute
       print(td.select("a")[0]["href"])

# This is method that scrape URL and if it doesnt get scraped, waits for 20 seconds and then tries again. (I use it because my internet connection sometimes get disconnects)
def tryAgain(passed_url):
    try:
        page  = requests.get(passed_url,headers = random.choice(header), timeout = timeout_time).text
        return page
    except Exception:
        while 1:
            print("Trying again the URL:")
            print(passed_url)
            try:
                page  = requests.get(passed_url,headers = random.choice(header), timeout = timeout_time).text
                print("-------------------------------------")
                print("---- URL was successfully scraped ---")
                print("-------------------------------------")
                return page
            except Exception:
                time.sleep(20)
                continue 

1

如果我们想从任何特定类别中获取商品名称,则可以通过使用CSS选择器指定该类别的类别名称来实现:

import requests ; from bs4 import BeautifulSoup

soup = BeautifulSoup(requests.get('https://www.flipkart.com/').text, "lxml")
for link in soup.select('div._2kSfQ4'):
    print(link.text)

这是部分搜索结果:

Puma, USPA, Adidas & moreUp to 70% OffMen's Shoes
Shirts, T-Shirts...Under ₹599For Men
Nike, UCB, Adidas & moreUnder ₹999Men's Sandals, Slippers
Philips & moreStarting 99LED Bulbs & Emergency Lights

0

这是一个简单的Web搜寻器,我使用BeautifulSoup,我们将搜索所有类名称为_3NFO0d的链接(锚)。我使用了Flipkar.com,它是一家在线零售商店。

import requests
from bs4 import BeautifulSoup
def crawl_flipkart():
    url = 'https://www.flipkart.com/'
    source_code = requests.get(url)
    plain_text = source_code.text
    soup = BeautifulSoup(plain_text, "lxml")
    for link in soup.findAll('a', {'class': '_3NFO0d'}):
        href = link.get('href')
        print(href)

crawl_flipkart()

0

Python有很好的选择来抓取网络。具有框架的最好的框架是令人毛骨悚然的。对于初学者来说可能有些棘手,所以这里有一些帮助。
1.在3.5以上安装python(直到2.7才可用)。
2.在conda中创建一个环境(我这样做了)。
3.将scrapy安装在某个位置,然后从那里运行。
4. Scrapy shell将为您提供一个交互式界面来测试您的代码。
5. Scrapy startproject projectname将创建一个框架。
6. Scrapy genspider spidername会制造蜘蛛。您可以根据需要创建任意数量的蜘蛛。在执行此操作时,请确保您位于项目目录中。


较容易的是使用要求漂亮的汤。在开始花一小时时间阅读文档之前,它将解决您的大部分疑问。BS4提供了广泛的解析器供您选择。使用user-agentsleep使刮擦更容易。BS4返回bs.tag,请使用variable[0]。如果正在运行js,您将无法直接使用request和bs4进行抓取。您可以获取api链接,然后解析JSON以获取所需的信息或尝试进行操作selenium

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.