无法以定制方式从网页获取输出

时间:2018-10-21 09:16:58

标签: python python-3.x web-scraping beautifulsoup

我已经用BeautiflSoup和Python结合使用选择器编写了一个脚本,以解析网页中的电影名称及其相应功能。当我执行脚本时,它会部分获取所需的项目。我如何获得所有电影名称及其特色?

我尝试过这样:

import requests
from bs4 import BeautifulSoup
from itertools import zip_longest

with requests.Session() as session:
    r = session.get('https://yts.am/browse-movies')
    soup = BeautifulSoup(r.text,"lxml")
    items = {item.text:itm.text for item,itm in zip(soup.select(".browse-movie-title"),soup.select("figcaption h4"))}
    print(items)

我喜欢的结果:

{'Halloween H20: 20 Years Later': '5.7 / 10', 'Rabbit': 'Horror', and so on-----

我想这是由于zip()函数的缘故。但是,我导入了zip_longest(),虽然可以解决问题,但我无法使用。

其中单个电影的此类功能所具有的HTML元素:

<figcaption class="hidden-xs hidden-sm">
<span class="icon-star"></span>
<h4 class="rating">5.7 / 10</h4>
<h4>Horror</h4>
<h4>Thriller</h4>
<span class="button-green-download2-big">View Details</span>
</figcaption>

这是一部电影的相关html:

<div class="browse-movie-bottom">
<a href="https://yts.am/movie/halloween-h20-20-years-later-1998" class="browse-movie-title">Halloween H20: 20 Years Later</a>
<div class="browse-movie-year">1998</div>
</div>

单个电影的预期输出:

'Halloween H20: 20 Years Later': ['5.7 / 10','Horror','Thriller']

1 个答案:

答案 0 :(得分:1)

您要一次选择所有元素。可能很难分组。 // // ViewController.swift // MapTest // // Created by Brandon on 2018-10-21. // Copyright © 2018 XIO. All rights reserved. // import UIKit import MapKit class ViewController: UIViewController, MKMapViewDelegate { private let mapView = { () -> MKMapView in let mapView = MKMapView() let span = MKCoordinateSpan(latitudeDelta: 0.005, longitudeDelta: 0.005) let location = CLLocationCoordinate2D(latitude: 43.6529, longitude: -79.3849) let region = MKCoordinateRegion(center: location, span: span) mapView.setRegion(region, animated: true) return mapView }() override func viewDidLoad() { super.viewDidLoad() mapView.delegate = self mapView.translatesAutoresizingMaskIntoConstraints = false mapView.register(CustomAnnotationView.self, forAnnotationViewWithReuseIdentifier: MKMapViewDefaultAnnotationViewReuseIdentifier) mapView.register(CustomClusterAnnotationView.self, forAnnotationViewWithReuseIdentifier: MKMapViewDefaultClusterAnnotationViewReuseIdentifier) view.addSubview(mapView) NSLayoutConstraint.activate([ mapView.leftAnchor.constraint(equalTo: view.leftAnchor), mapView.rightAnchor.constraint(equalTo: view.rightAnchor), mapView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor), mapView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor) ]) let annotation1 = CustomAnnotation(coordinate: CLLocationCoordinate2D(latitude: 43.6529, longitude: -79.3849)) let annotation2 = CustomAnnotation(coordinate: CLLocationCoordinate2D(latitude: 43.65291, longitude: -79.3849)) let annotation3 = CustomAnnotation(coordinate: CLLocationCoordinate2D(latitude: 43.6528, longitude: -79.3849)) let annotation4 = CustomAnnotation(coordinate: CLLocationCoordinate2D(latitude: 43.6527, longitude: -79.3848)) mapView.addAnnotations([annotation1, annotation2, annotation3, annotation4]) } func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? { if let annotation = annotation as? CustomAnnotation { var annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: MKMapViewDefaultAnnotationViewReuseIdentifier, for: annotation) as? CustomAnnotationView if annotationView == nil { annotationView = CustomAnnotationView(annotation: annotation, reuseIdentifier: MKMapViewDefaultAnnotationViewReuseIdentifier) } annotationView?.clusteringIdentifier = "ClusteringID" return annotationView } if let annotation = annotation as? CustomClusterAnnotation { var annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: MKMapViewDefaultClusterAnnotationViewReuseIdentifier, for: annotation) as? CustomClusterAnnotationView if annotationView == nil { annotationView = CustomClusterAnnotationView(annotation: annotation, reuseIdentifier: MKMapViewDefaultClusterAnnotationViewReuseIdentifier) } annotationView?.onPinTapped = { [weak self] pin in if let annotation = pin.annotation as? CustomClusterAnnotation, let mapView = self?.mapView { mapView.showAnnotations(annotation.memberAnnotations, animated: true) // let point = MKMapPoint(annotation.coordinate) // var rect = mapView.visibleMapRect // rect.size.width = 10.0 // rect.size.height = 10.0 // // rect.origin.x = point.x - rect.size.width * 0.5 // rect.origin.y = point.y - rect.size.height * 0.5 // mapView.setVisibleMapRect(rect, animated: true) } } return annotationView } return nil } func mapView(_ mapView: MKMapView, clusterAnnotationForMemberAnnotations memberAnnotations: [MKAnnotation]) -> MKClusterAnnotation { return CustomClusterAnnotation(memberAnnotations: memberAnnotations) } } //Just some custom annotation views.. class CustomAnnotation: NSObject, MKAnnotation { var coordinate: CLLocationCoordinate2D var title: String? var subtitle: String? init(coordinate: CLLocationCoordinate2D) { self.coordinate = coordinate } } class CustomClusterAnnotation: MKClusterAnnotation { override init(memberAnnotations: [MKAnnotation]) { super.init(memberAnnotations: memberAnnotations) title = "\(memberAnnotations.count)" subtitle = nil } } class CustomAnnotationView: MKAnnotationView { override init(annotation: MKAnnotation?, reuseIdentifier: String?) { super.init(annotation: annotation, reuseIdentifier: reuseIdentifier) self.isUserInteractionEnabled = true //image = #imageLiteral(resourceName: "map-annotation") if image == nil { let displayView = UIView() displayView.translatesAutoresizingMaskIntoConstraints = false displayView.backgroundColor = .red displayView.layer.cornerRadius = 5.0 addSubview(displayView) NSLayoutConstraint.activate([ displayView.widthAnchor.constraint(equalTo: displayView.heightAnchor), displayView.centerXAnchor.constraint(equalTo: centerXAnchor), displayView.centerYAnchor.constraint(equalTo: centerYAnchor), displayView.heightAnchor.constraint(equalToConstant: 10.0) ]) } } @available(*, unavailable) required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } } class CustomClusterAnnotationView: MKAnnotationView { var onPinTapped: ((CustomClusterAnnotationView) -> Void)? private let titleLabel = { () -> UILabel in let label = UILabel() label.textColor = .white label.font = UIFont.systemFont(ofSize: 25.0, weight: .bold) label.numberOfLines = 0 label.textAlignment = .center label.translatesAutoresizingMaskIntoConstraints = false return label }() private let backgroundView = { () -> UIView in let view = UIView() view.layer.masksToBounds = true view.backgroundColor = .blue view.isUserInteractionEnabled = true view.translatesAutoresizingMaskIntoConstraints = false return view }() override init(annotation: MKAnnotation?, reuseIdentifier: String?) { super.init(annotation: annotation, reuseIdentifier: reuseIdentifier) self.isUserInteractionEnabled = true addSubview(backgroundView) backgroundView.addSubview(titleLabel) NSLayoutConstraint.activate([ titleLabel.leftAnchor.constraint(equalTo: backgroundView.leftAnchor, constant: 5.0), titleLabel.rightAnchor.constraint(equalTo: backgroundView.rightAnchor, constant: -5.0), titleLabel.topAnchor.constraint(equalTo: backgroundView.topAnchor, constant: 5.0), titleLabel.bottomAnchor.constraint(equalTo: backgroundView.bottomAnchor, constant: -5.0) ]) NSLayoutConstraint.activate([ backgroundView.widthAnchor.constraint(equalTo: backgroundView.heightAnchor), backgroundView.centerXAnchor.constraint(equalTo: centerXAnchor), backgroundView.centerYAnchor.constraint(equalTo: centerYAnchor) ]) let gestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(onPinTapped(_:))) gestureRecognizer.numberOfTouchesRequired = 1 gestureRecognizer.numberOfTapsRequired = 1 backgroundView.addGestureRecognizer(gestureRecognizer) } @available(*, unavailable) required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } override var annotation: MKAnnotation? { willSet { guard let annotation = newValue as? MKClusterAnnotation else { return } titleLabel.text = "\(annotation.memberAnnotations.count)" } } override func layoutSubviews() { super.layoutSubviews() backgroundView.layer.cornerRadius = backgroundView.bounds.height / 2.0 bounds = backgroundView.bounds } override func prepareForReuse() { super.prepareForReuse() bounds = backgroundView.bounds } @objc private func onPinTapped(_ gestureRecognizer: UITapGestureRecognizer) { onPinTapped?(self) } } 也不是您想要的东西。只需遍历卡片即可。

zip

输出将是

import requests
from bs4 import BeautifulSoup

with requests.Session() as session:
    r = session.get('https://yts.am/browse-movies')
    soup = BeautifulSoup(r.text,"lxml")  

    for movie in soup.select("div.browse-movie-wrap"):
        title = movie.select_one('a.browse-movie-title').text
        details = [detail.text for detail in movie.select('h4')]
        print((title, details))